C#操作IIS完整解析
A :版本問題這是你在進(jìn)行編程前必須要要考慮的一個實際問題. 因為IIS 版本不同對應(yīng)編程上基本上完全不同方式來進(jìn)行的. 先了解一下Iss 版本在操作系統(tǒng)個具體要求.ISS6.0時代主要以using
A :版本問題
這是你在進(jìn)行編程前必須要要考慮的一個實際問題. 因為IIS 版本不同對應(yīng)編程上基本上完全不同方式來進(jìn)行的. 先了解一下Iss 版本在操作系統(tǒng)個具體要求.
ISS6.0時代主要以using System.DirectoryServices 空間下的Directory Entry 對象作為編程訪問一個主要載體. 但隨著ISS 7.0發(fā)布.NET 的Web 程序由ISS6.0開始逐漸過渡到 7.0版本. 而且在編程控制ISS 上新添加的Microsoft.Web.Administration 名稱空間, 提出多個用于管理 操作 和訪問ISS 的對象, 使操作ISS 的編程更加簡潔 高效.
B:我們要做什么
實際用戶操作環(huán)境中主要以Windows XP/2000/2003操作系統(tǒng)為主, 這就導(dǎo)致了ISS 版本主要在5. 0/5.1/6.0之間, 所以本次演示的代碼編程實例都是ISS 7.0版本以下(不包含Iss7.0).
為了達(dá)到演示目的, 我們現(xiàn)在需求是這樣的: 把硬盤上Silverlight 應(yīng)用程序成功部署到本地機器ISS 上. 并支持通過局域網(wǎng)訪問. 需求很簡單吧就是一句話, 其實當(dāng)進(jìn)入實際編程時因為客戶的局域網(wǎng)環(huán)境是不可預(yù)知的, 這也就導(dǎo)致影響部署Silverlight 程序到ISS 上諸多未知因素. 所以要在編程中使Si lverlight 應(yīng)用程序部署成功, 我們必須利用編程除了控制ISS 外還要控制其他主要影響ISS 因素

.
,C:進(jìn)入編程
既然提出需求我
們大概確定一下
解決思路:
在默認(rèn)站點下創(chuàng)建一個虛擬目錄承載Silverlight 應(yīng)用程序, 新建的虛擬目錄運行在獨立應(yīng)用程序池中, 支持本地局域網(wǎng)匿名訪問其實就是對訪問權(quán)限控制, 為了直接使更改的應(yīng)用生效需要多次重新啟動ISS 的服務(wù), 這就需要對ISS 服務(wù)進(jìn)行編程控制.
<1>ISS版本的獲取
在進(jìn)入客戶環(huán)境前我們先檢測下是否存在安裝了ISS, 以及ISS 版本獲取提示, 目前獲取ISS 版本的方式主要有兩種, 第一種方法是通過遍歷Directory Entry 實體目錄 第二種方式是通過獲取注冊表的ISS 修改版本值[經(jīng)測試這種方式獲取版本不穩(wěn)定].
1: public static void GetIssVersionByDri(string domainname) 2: {
3: try
4: {
5: if (string.IsNullOrEmpty(domainname))
6: {
7: //如果為空 則默認(rèn)為本地機器
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: //說明一點:IIS5.0中沒有(int)entry.Properties["MajorIISVersionNumber"].Value;屬性,將拋出異常 證明版本為 5.0
17: MessageBox.Show("獲取ISS 的版本是發(fā)生異常信息:" se.Message);
18: }
19: }
通過系統(tǒng)注冊表獲取ISS 版本的值:[測試發(fā)現(xiàn)不穩(wěn)定] 1: public static string GetIssVersion()
2: {
3: //RegistryKey表示 Windows 注冊表中的項級節(jié)點. 此類是注冊表封裝
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)建虛擬目錄
每個Internet 服務(wù)可以從多個目錄中發(fā)布, 通過以通用命名約定 (UNC) 名、用戶名及用于訪問權(quán)限的密碼指定目錄,可將每個目錄定位在本地驅(qū)動器或網(wǎng)絡(luò)上, 虛擬目錄可以一個宿主程序, 這可發(fā)布的操作目錄即為虛擬目錄. 再來看看在ISS6.0中創(chuàng)建的虛擬目錄的步驟和控制的屬性.
新建虛擬目錄:
1: ///
2: /// 添加一個虛擬目錄
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)頁:
,27: newVirDir.Properties["EnableDefaultDoc" ][0] = t rue ;
28: newVirDir.Properties["DefaultDoc" ][0] =

"Defaul t.aspx" ;
29:
30: //_newVirDir
31: newVirDir.CommitChanges();
32: }
這個方法在創(chuàng)建時主要有兩個參數(shù) 一個是新建虛擬目錄名稱 另外一個要部署Silverlight 應(yīng)用程序物理路徑. 在獲取根節(jié)目錄時需要制定ISS 的路徑. ISS的路徑格式如:IIS://ComputerName/Service/Website/Directory
,找到根目錄后添加新建虛擬目錄. 制定參數(shù)為Schema-指每個結(jié)點的類型:IIsVirtualDir:——虛擬目錄 IIsWebDir :——普通目錄, 添加完成后調(diào)用ADSI 中的"AppCreate" 方法將目錄真正創(chuàng)建. 創(chuàng)建完成后通過根目錄和新目錄提交保存.
<3>目錄屬性設(shè)置
在DirectoryEntity 虛擬目錄屬性可以說是非常多的, 當(dāng)時在編程時我為了區(qū)分屬性間區(qū)別做了一個方法去遍歷整個屬性集合PropertyCollection. 然后把常用重要的屬性跳出來進(jìn)入賦值設(shè)置. 因為關(guān)于虛擬目錄的屬性在MSDN 上的API 中并沒有直接提到, 特別是對虛擬目錄訪問權(quán)限控制非常重要屬性等 .先說明局部的常用的屬性:
例如修改程序起始頁: 1: //設(shè)置起始默認(rèn)頁:

2: newVirDir.Properties["EnableDefaultDoc" ][0] = true ;
,3: newVirDir.Properties["DefaultDoc" ][0] = "Default.asp x,Index.Html,index.asp" ;
4: newVirDir.CommitChanges();
DefaultDoc 選項可以支持多個但注意選擇性排序. 一般修改目錄屬性后都選通過CommitChanges()方法提交保存, 但有時你會發(fā)現(xiàn)我明明修改屬性 卻沒有保存生效. 這是因為ISS 中部分屬性設(shè)置需要重新啟動ISS 服務(wù)才能生效. 這個時候我們需要對ISS 服務(wù)進(jìn)行控制.
<4>ISS服務(wù)控制
關(guān)于ISS 服務(wù)控制微軟提供一個命名空間System.ServiceProcess 提供能夠快速操作本地系統(tǒng)服務(wù)A PI. 對于ISS 服務(wù)控制我們最常用的是重新啟動使當(dāng)前設(shè)置生效. 在設(shè)置服務(wù)時我先找到服務(wù)名稱, 打開計算機管理 在服務(wù)和應(yīng)用程序目錄下打開服務(wù).
我們能看到ISS 服務(wù)命名是:ISSAdmin 我們通過編碼來控制:啟動ISS. 1: //獲取IIS Serivcer控制聲明 . 參數(shù)為Server 在系統(tǒng)標(biāo)識該服務(wù)的簡稱

,.
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提供對本地和遠(yuǎn)程進(jìn)程的訪問并使您能夠啟動和停止本地系統(tǒng)進(jìn)程
9: //利用Start 方法調(diào)用:啟動(或重用)此 Process 組件的 StartInfo 屬性指定的進(jìn)程資源,并將其與該組件關(guān)聯(lián)
10: //如果啟動了進(jìn)程資源,則為 true;如果沒有啟動新的進(jìn)程資源(例如,如果重用了現(xiàn)有進(jìn)程),則為 false
11: //通過指定文檔或應(yīng)用程序文件的名稱來啟動進(jìn)程資源,并將資源與新的 Process 組件關(guān)聯(lián)
12: Process.Start("iisreset" );
13: }
如上就是簡單利用編程有效控制ISS 服務(wù)運行狀態(tài).
<5>應(yīng)用程序池創(chuàng)建與控制
ISS 應(yīng)用程序池是將一個或多個應(yīng)用程序鏈接到一個或多個工作進(jìn)程集合的配置。因為應(yīng)用程序池中的應(yīng)用程序與其他應(yīng)用程序被工作進(jìn)程邊界分隔,所以某個應(yīng)用程序池中的應(yīng)用程序不會受到其他應(yīng)
,用程序池中應(yīng)用程序所產(chǎn)生的問題的影響, 當(dāng)我們新建一個應(yīng)用程序時 有時客戶端環(huán)境我們無法清除預(yù)知, 為了盡量減少影響ISS 設(shè)置外在因素, 我們把新建虛擬目錄放到一個獨立應(yīng)用程序池中. 當(dāng)創(chuàng)建一個虛擬目錄后, 也同時創(chuàng)建一個程序池 把虛擬目錄放到其中: 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: //第一次測試根目錄
14: foreach (DirectoryEntry getchild in getentity.Children)
15: {