C#操作IIS完整解析
A :版本問(wèn)題這是你在進(jìn)行編程前必須要要考慮的一個(gè)實(shí)際問(wèn)題. 因?yàn)镮IS 版本不同對(duì)應(yīng)編程上基本上完全不同方式來(lái)進(jìn)行的. 先了解一下Iss 版本在操作系統(tǒng)個(gè)具體要求.ISS6.0時(shí)代主要以u(píng)sing
A :版本問(wèn)題
這是你在進(jìn)行編程前必須要要考慮的一個(gè)實(shí)際問(wèn)題. 因?yàn)镮IS 版本不同對(duì)應(yīng)編程上基本上完全不同方式來(lái)進(jìn)行的. 先了解一下Iss 版本在操作系統(tǒng)個(gè)具體要求.
ISS6.0時(shí)代主要以u(píng)sing System.DirectoryServices 空間下的Directory Entry 對(duì)象作為編程訪問(wèn)一個(gè)主要載體. 但隨著ISS 7.0發(fā)布.NET 的Web 程序由ISS6.0開(kāi)始逐漸過(guò)渡到 7.0版本. 而且在編程控制ISS 上新添加的Microsoft.Web.Administration 名稱空間, 提出多個(gè)用于管理 操作 和訪問(wèn)ISS 的對(duì)象, 使操作ISS 的編程更加簡(jiǎn)潔 高效.
B:我們要做什么
實(shí)際用戶操作環(huán)境中主要以Windows XP/2000/2003操作系統(tǒng)為主, 這就導(dǎo)致了ISS 版本主要在5. 0/5.1/6.0之間, 所以本次演示的代碼編程實(shí)例都是ISS 7.0版本以下(不包含Iss7.0).
為了達(dá)到演示目的, 我們現(xiàn)在需求是這樣的: 把硬盤上Silverlight 應(yīng)用程序成功部署到本地機(jī)器ISS 上. 并支持通過(guò)局域網(wǎng)訪問(wèn). 需求很簡(jiǎn)單吧就是一句話, 其實(shí)當(dāng)進(jìn)入實(shí)際編程時(shí)因?yàn)榭蛻舻木钟蚓W(wǎng)環(huán)境是不可預(yù)知的, 這也就導(dǎo)致影響部署Silverlight 程序到ISS 上諸多未知因素. 所以要在編程中使Si lverlight 應(yīng)用程序部署成功, 我們必須利用編程除了控制ISS 外還要控制其他主要影響ISS 因素
.
,C:進(jìn)入編程
既然提出需求我
們大概確定一下
解決思路:
在默認(rèn)站點(diǎn)下創(chuàng)建一個(gè)虛擬目錄承載Silverlight 應(yīng)用程序, 新建的虛擬目錄運(yùn)行在獨(dú)立應(yīng)用程序池中, 支持本地局域網(wǎng)匿名訪問(wèn)其實(shí)就是對(duì)訪問(wèn)權(quán)限控制, 為了直接使更改的應(yīng)用生效需要多次重新啟動(dòng)ISS 的服務(wù), 這就需要對(duì)ISS 服務(wù)進(jìn)行編程控制.
<1>ISS版本的獲取
在進(jìn)入客戶環(huán)境前我們先檢測(cè)下是否存在安裝了ISS, 以及ISS 版本獲取提示, 目前獲取ISS 版本的方式主要有兩種, 第一種方法是通過(guò)遍歷Directory Entry 實(shí)體目錄 第二種方式是通過(guò)獲取注冊(cè)表的ISS 修改版本值[經(jīng)測(cè)試這種方式獲取版本不穩(wěn)定].
1: public static void GetIssVersionByDri(string domainname) 2: {
3: try
4: {
5: if (string.IsNullOrEmpty(domainname))
6: {
7: //如果為空 則默認(rèn)為本地機(jī)器
8: domainname = "LOCALHOST";
9: }
10: DirectoryEntry getEntity=new DirectoryEntry("IIS:
//" domainname "/W3SVC/INFO");
,11: string Version=getEntity.Properties["MajorIISVersionNumber"].Value.ToString();
12: MessageBox.Show(Version);
13: }
14: catch (Exception se)
15: {
16: //說(shuō)明一點(diǎn):IIS5.0中沒(méi)有(int)entry.Properties["MajorIISVersionNumber"].Value;屬性,將拋出異常 證明版本為 5.0
17: MessageBox.Show("獲取ISS 的版本是發(fā)生異常信息:" se.Message);
18: }
19: }
通過(guò)系統(tǒng)注冊(cè)表獲取ISS 版本的值:[測(cè)試發(fā)現(xiàn)不穩(wěn)定] 1: public static string GetIssVersion()
2: {
3: //RegistryKey表示 Windows 注冊(cè)表中的項(xiàng)級(jí)節(jié)點(diǎn). 此類是注冊(cè)表封裝
4: string issversion = string .Empty;
5: RegistryKey getkey = Registry.LocalMachine.OpenSubKey("softwaremicrosoftinetstp");
6: if (getkey != null )
7: {
8: issversion= Convert.ToInt32(getkey.GetValue("majorv ersion" , -1)).ToString();
,9: MessageBox.Show(issversion.ToString());
10: } 11:
return iss
version;
12: }
<2>創(chuàng)建虛擬目錄
每個(gè)Internet 服務(wù)可以從多個(gè)目錄中發(fā)布, 通過(guò)以通用命名約定 (UNC) 名、用戶名及用于訪問(wèn)權(quán)限的密碼指定目錄,可將每個(gè)目錄定位在本地驅(qū)動(dòng)器或網(wǎng)絡(luò)上, 虛擬目錄可以一個(gè)宿主程序, 這可發(fā)布的操作目錄即為虛擬目錄. 再來(lái)看看在ISS6.0中創(chuàng)建的虛擬目錄的步驟和控制的屬性.
新建虛擬目錄:
1: ///
2: /// 添加一個(gè)虛擬目錄
3: ///
4: public void CreateVirtualDir(string virtualdirname, string logicDir)
5: {
6: //如果存在重復(fù) 就直接刪除虛擬目錄
7: if (IsExitesVirtualDir(virtualdirname))
,8: DeleteVirtualDir(virtualdirname);
9:
10: DirectoryEntry rootEntry;
11: rootEntry = new DirectoryEntry("IIS://localhost/W3SVC/1/root");
12:
13: DirectoryEntry newVirDir;
14: newVirDir = rootEntry.Children.Add(virtualdirname, "IIsWebVirtualDir" );
15: newVirDir.Invoke("AppCreate" , true );
16:
17: newVirDir.CommitChanges();
18: rootEntry.CommitChanges();
19:
20: newVirDir.Properties["AnonymousPasswordSync" ][0] = true ;
21: newVirDir.Properties["Path" ][0] = logicDir;// @"virtualdirentryvirtualname";
22:
23: //設(shè)置的端口綁定數(shù)據(jù)
24: //_newVirDir.Properties["ServerBindings"].Value =AppEntitys.WebAppInfor.HostIp AppEntitys.WebAppInfor.HostProt AppEntitys.WebAppInfor.AppDesc;
25:
26: //設(shè)置起始默認(rèn)頁(yè):
,27: newVirDir.Properties["EnableDefaultDoc" ][0] = t rue ;
28: newVirDir.Properties["DefaultDoc" ][0] =
"Defaul t.aspx" ;
29:
30: //_newVirDir
31: newVirDir.CommitChanges();
32: }
這個(gè)方法在創(chuàng)建時(shí)主要有兩個(gè)參數(shù) 一個(gè)是新建虛擬目錄名稱 另外一個(gè)要部署Silverlight 應(yīng)用程序物理路徑. 在獲取根節(jié)目錄時(shí)需要制定ISS 的路徑. ISS的路徑格式如:IIS://ComputerName/Service/Website/Directory
,找到根目錄后添加新建虛擬目錄. 制定參數(shù)為Schema-指每個(gè)結(jié)點(diǎn)的類型:IIsVirtualDir:——虛擬目錄 IIsWebDir :——普通目錄, 添加完成后調(diào)用ADSI 中的"AppCreate" 方法將目錄真正創(chuàng)建. 創(chuàng)建完成后通過(guò)根目錄和新目錄提交保存.
<3>目錄屬性設(shè)置
在DirectoryEntity 虛擬目錄屬性可以說(shuō)是非常多的, 當(dāng)時(shí)在編程時(shí)我為了區(qū)分屬性間區(qū)別做了一個(gè)方法去遍歷整個(gè)屬性集合PropertyCollection. 然后把常用重要的屬性跳出來(lái)進(jìn)入賦值設(shè)置. 因?yàn)殛P(guān)于虛擬目錄的屬性在MSDN 上的API 中并沒(méi)有直接提到, 特別是對(duì)虛擬目錄訪問(wèn)權(quán)限控制非常重要屬性等 .先說(shuō)明局部的常用的屬性:
例如修改程序起始頁(yè): 1: //設(shè)置起始默認(rèn)頁(yè):
2: newVirDir.Properties["EnableDefaultDoc" ][0] = true ;
,3: newVirDir.Properties["DefaultDoc" ][0] = "Default.asp x,Index.Html,index.asp" ;
4: newVirDir.CommitChanges();
DefaultDoc 選項(xiàng)可以支持多個(gè)但注意選擇性排序. 一般修改目錄屬性后都選通過(guò)CommitChanges()方法提交保存, 但有時(shí)你會(huì)發(fā)現(xiàn)我明明修改屬性 卻沒(méi)有保存生效. 這是因?yàn)镮SS 中部分屬性設(shè)置需要重新啟動(dòng)ISS 服務(wù)才能生效. 這個(gè)時(shí)候我們需要對(duì)ISS 服務(wù)進(jìn)行控制.
<4>ISS服務(wù)控制
關(guān)于ISS 服務(wù)控制微軟提供一個(gè)命名空間System.ServiceProcess 提供能夠快速操作本地系統(tǒng)服務(wù)A PI. 對(duì)于ISS 服務(wù)控制我們最常用的是重新啟動(dòng)使當(dāng)前設(shè)置生效. 在設(shè)置服務(wù)時(shí)我先找到服務(wù)名稱, 打開(kāi)計(jì)算機(jī)管理 在服務(wù)和應(yīng)用程序目錄下打開(kāi)服務(wù).
我們能看到ISS 服務(wù)命名是:ISSAdmin 我們通過(guò)編碼來(lái)控制:啟動(dòng)ISS. 1: //獲取IIS Serivcer控制聲明 . 參數(shù)為Server 在系統(tǒng)標(biāo)識(shí)該服務(wù)的簡(jiǎn)稱
,.
2: ServiceController getservicecon = new ServiceController("IISADMIN" );
3: getservicecon.Start();
重啟/暫停/停止ISS 服務(wù):
,1: if (getservicecon.Status == ServiceControllerStatus.Running)
2: {
3: //停止服務(wù)
4: getservicecon.Stop();
5: //暫停服務(wù)
6: getservicecon.Pause();
7: //重啟服務(wù)
8: //Process提供對(duì)本地和遠(yuǎn)程進(jìn)程的訪問(wèn)并使您能夠啟動(dòng)和停止本地系統(tǒng)進(jìn)程
9: //利用Start 方法調(diào)用:啟動(dòng)(或重用)此 Process 組件的 StartInfo 屬性指定的進(jìn)程資源,并將其與該組件關(guān)聯(lián)
10: //如果啟動(dòng)了進(jìn)程資源,則為 true;如果沒(méi)有啟動(dòng)新的進(jìn)程資源(例如,如果重用了現(xiàn)有進(jìn)程),則為 false
11: //通過(guò)指定文檔或應(yīng)用程序文件的名稱來(lái)啟動(dòng)進(jìn)程資源,并將資源與新的 Process 組件關(guān)聯(lián)
12: Process.Start("iisreset" );
13: }
如上就是簡(jiǎn)單利用編程有效控制ISS 服務(wù)運(yùn)行狀態(tài).
<5>應(yīng)用程序池創(chuàng)建與控制
ISS 應(yīng)用程序池是將一個(gè)或多個(gè)應(yīng)用程序鏈接到一個(gè)或多個(gè)工作進(jìn)程集合的配置。因?yàn)閼?yīng)用程序池中的應(yīng)用程序與其他應(yīng)用程序被工作進(jìn)程邊界分隔,所以某個(gè)應(yīng)用程序池中的應(yīng)用程序不會(huì)受到其他應(yīng)
,用程序池中應(yīng)用程序所產(chǎn)生的問(wèn)題的影響, 當(dāng)我們新建一個(gè)應(yīng)用程序時(shí) 有時(shí)客戶端環(huán)境我們無(wú)法清除預(yù)知, 為了盡量減少影響ISS 設(shè)置外在因素, 我們把新建虛擬目錄放到一個(gè)獨(dú)立應(yīng)用程序池中. 當(dāng)創(chuàng)建一個(gè)虛擬目錄后, 也同時(shí)創(chuàng)建一個(gè)程序池 把虛擬目錄放到其中: 1: ///
2: /// 建立程序池后關(guān)聯(lián)相應(yīng)應(yīng)用程序及虛擬目錄
3: ///
4: public static void SetAppToPool(string appname) 5: {
6: //獲取目錄
7: DirectoryEntry getdir = new DirectoryEntry("IIS://localhost/W3SVC");
8: foreach (DirectoryEntry getentity in getdir.Children)
9: {
10: if (getentity.SchemaClassName.Equals("IIsWe bServer" ))
11: {
12: //設(shè)置應(yīng)用程序程序池 先獲得應(yīng)用程序 在設(shè)定應(yīng)用程序程序池
13: //第一次測(cè)試根目錄
14: foreach (DirectoryEntry getchild in getentity.Children)
15: {