Share via


IIS 7.0 開發人員的端對端擴充性範例

Saad Ladki

IIS 7 和更新版本是以完全模組化的架構為基礎,建置在豐富的擴充性 API 之上。 這可讓開發人員輕鬆地新增、移除甚至取代內建 IIS 元件,並搭配手動製作,特別適合任何指定的網站。 將程式碼深入插入 IIS 核心管線,並透過之前不可能的方式擴充 IIS,一直不容易。

為了提供一些範例:幾行程式碼可讓開發人員撰寫提供新驗證和授權配置的模組或處理常式、執行連入要求的執行時間或安全性分析,並檢查回應。 但若要提供真正的值新增,這些模組必須可透過程式設計介面、命令列工具和使用者介面來管理。

本白皮書是如何使用自訂要求處理常式擴充 IIS 網頁伺服器的端對端範例。 它示範如何新增此處理程式設定的 API 和命令列支援,以及如何將使用者介面模組插入 IIS 管理介面。

此解決方案已在 Windows Vista 和 Windows Server® 2008 Beta 3 上進行測試。 一旦 Windows Server 2008 的最終版本可供使用,就會更新它。

功能集

  • Managed 處理常式會將著作權訊息插入影像檔
  • 著作權訊息功能是設定驅動,並使用新的 IIS 組態系統
  • 設定可以架構化,並可存取設定 API、WMI 腳本和 IIS 命令列工具
  • 使用者介面延伸模組允許透過 IIS 使用者介面設定著作權訊息功能

必要條件

若要遵循本檔中的步驟,必須安裝下列軟體:

ASP.NET

透過 Windows Vista 主控台安裝 ASP.NET。 選取 [程式] - [開啟或關閉 Windows 功能]。 然後開啟 「Internet Information Services」 - 「World Wide Web Services」 - 應用程式開發功能],然後檢查 [ASP.NET]。

如果您有 Windows Server 2008 組建。 開啟 [伺服器管理員] - [管理角色],然後選取 [網頁伺服器 (IIS) ]。 按一下 [新增角色服務]。 在 [應用程式開發] 底下,檢查 [ASP.NET]。

您也必須安裝「IIS 管理腳本和工具」,以利用 IIS 中的 WMI 擴充性。 若要這樣做,請選取 [程式] - [開啟或關閉 Windows 功能]。 然後開啟 「Internet Information Services」 - 「Web Management Tools」,並檢查 [IIS 管理腳本和工具]。

如果您有 Windows Server 2008 組建,請開啟 [伺服器管理員] - [角色],然後選取 [Web Server (IIS) ]。 按一下 [新增角色服務]。 在 [Web 管理工具] 底下,核取 [IIS 管理腳本和工具]。

Visual C# Express Edition 或 Visual Studio 2005

針對使用者介面模組,您需要 C# 開發工具。 如果您沒有 Visual Studio 2005 的複本,請免費 下載 Visual Studio

處理使用者帳戶控制問題

Windows Vista 使用者帳戶保護會從您的存取權杖中移除系統管理員許可權。 根據預設,您將無法存取 IIS 組態和內容位置。 若要修正此問題,建議您使用提升許可權的命令提示字元進行本文。

若要啟動提升許可權的命令提示字元,請移至 [開始] 功能表,按一下 [所有程式] - [配件]。 以滑鼠右鍵按一下 [命令提示字元],然後按一下 [以系統管理員身分執行]。 確認提高許可權提示。

狀況

下列範例會以左下角的著作權資訊動態裝飾網頁伺服器所提供的影像,如圖 1 所示。

網頁的螢幕擷取畫面,其中顯示雲端天底上雪地覆蓋岩石的影像。
圖 1:影像著作權模組作用中

我們使用 Managed 程式碼來開發裝飾影像的處理常式。 在範例中,我們也指定此處理程式的組態,並將其儲存在 IIS 組態存放區中。 最後,我們將開發 IIS 管理員的使用者介面外掛程式。

只要將架構檔案複製到 IIS 架構目錄,即可擴充 IIS 組態存放區。 架構會宣告新組態區段的名稱及其屬性、類型和預設值。 在我們的範例中,我們會宣告名為 imageCopyright 的新組態區段。 它位於 system.webServer 組態群組內。 其屬性為:

  • 布林值旗標,可啟用或停用 imageCopyright 功能
  • 包含著作權訊息的字串屬性
  • 指定著作權訊息色彩的色彩屬性

架構宣告

將下列架構定義儲存為 中的 %windir%\system32\inetsrv\config\schema imagecopyright.xml:

<configSchema>
    <sectionSchema name="system.webServer/imageCopyright">
        <attribute name="enabled" type="bool" defaultValue="false" />
        <attribute name="message" type="string" defaultValue="Your Copyright Message" />
        <attribute name="color" type="string" defaultValue="Red"/> 
   </sectionSchema>
</configSchema>

如果您收到「拒絕存取」訊息,則未從提升許可權的命令提示字元執行此動作。 新增架構檔案之後,必須在applicationhost.config檔案中宣告架構。 將下列 XML 新增至 %windir%\system32\inetsrv\config\applicationhost.config

<configSections>
...
<sectionGroup name="system.webServer">
<section name="imageCopyright"  overrideModeDefault="Allow"/>
...    
</sectionGroup>
</configSections>

設定它

此程式已完成。 您可以透過命令列或直接在applicationhost.config或web.config內設定新的組態設定。試試看。 開啟命令殼層,然後輸入下列命令:

<system.webServer>
    <imageCopyright />
</system.webServer>

輸出會顯示已辨識組態區段及其預設組態:

%windir%\system32\inetsrv\appcmd set config -section:system.webServer/imageCopyright 

/color:yellow /message:"Copyright (C) Contoso.COM" /enabled:true

現在,透過appcmd.exe新增組態設定,例如

%windir%\system32\inetsrv\appcmd set config -section:system.webServer/imageCopyright 

/color:yellow /message:"Copyright (C) Contoso.COM" /enabled:true

檢查是否已執行下列命令來儲存組態:

%windir%\system32\inetsrv\appcmd list config -section:system.webServer/imageCopyright

請參閱已儲存的組態:

<system.webServer> 
    <imageCopyright enabled="true" message="Copyright (C) Contoso.COM" color="yellow" />
</system.webServer>

讓 imageCopyright 組態可編寫腳本

注意

讓 imageCopyright 處理常式組態可供 WMI 腳本使用是選擇性的。 您可以直接移至「步驟 2 – 核心擴充性:映射著作權處理常式」,而不會影響其餘步驟。

若要讓 imageCopyright 處理常式組態可供 WMI 腳本使用,請完成下列步驟:

  • 安裝 IIS WMI 支援
  • 建立 imageCopyright.mof 檔案
  • 將 imageCopyright.mof 檔案納入 webadministration.mof,以及 WMI 架構檔案的編譯
  • 撰寫和執行腳本

安裝 IIS WMI 支援

IIS 的預設安裝不包含 WMI 腳本元件。 您必須新增它們。

在 Vista 用戶端 SKU 上安裝 WMI 支援

透過 Windows Vista 主控台安裝「IIS 管理腳本和工具」。 選取 [程式] - [開啟或關閉 Windows 功能]。 然後開啟 [Internet Information Services] - [Web 管理工具],然後檢查 [IIS 管理腳本和工具]。

在 Windows Server 2008 SKU 上安裝 WMI 支援

如果您有 Windows Server 2008 組建,請開啟 [伺服器管理員] - [角色],然後選取 [Web Server (IIS) ]。 按一下 [新增角色服務]。 在 [管理工具] 底下,檢查 [IIS 管理腳本和工具]。

建立 imageCopyright.mof 檔案

WMI 屬性的架構宣告與上一個步驟中的 IIS 屬性架構宣告非常類似。 WMI 架構會在 .mof 檔案中宣告,並由名為 mofcomp 的工具編譯。 Mofcomp 會將架構宣告新增至 WMI 存放庫。

新增架構資訊的工作

開啟記事本實例,並將下列幾行複製到其中:

#pragma AUTORECOVER
#pragma namespace("\\\\.\\Root\\WebAdministration")
[            
    dynamic : ToInstance ToSubClass,
    provider("WebAdministrationProvider") : ToInstance ToSubClass,
    Description("imageCopyright Section") : ToSubClass,
    Locale(1033) : ToInstance ToSubClass,
    factory_clsid("{901a70b2-0f7a-44ea-b97b-1e9299dec8ca}"),
    section_path("system.webServer/imageCopyright"),
    SupportsUpdate
]
 
class imageCopyright : ConfigurationSection
{      
    [
        read: ToSubClass ToInstance,
        write: ToSubClass ToInstance,
        DefaultValue("False"): ToSubClass ToInstance,
        Description("To be written"): ToSubClass ToInstance
    ]
    boolean Enabled;
  
    [
        read: ToSubClass ToInstance,
        write: ToSubClass ToInstance,
        DefaultValue("Your Copyright Message"): ToSubClass ToInstance,
        Description("Copyright Message"): ToSubClass ToInstance
    ]
    string Message;

    [
        read: ToSubClass ToInstance,
        write: ToSubClass ToInstance,
        DefaultValue("Yellow"): ToSubClass ToInstance,
        Description("Color of Copyright Message"): ToSubClass ToInstance
    ]
    string Color;
};

架構宣告包含與上一個步驟中imageCopyright.xml相同的專案,也就是組態設定的名稱和類型及其預設值。 將檔案儲存為 %windir%\system32\inetsrv\imageCopyright.mof

WMI 架構檔案的編譯

執行下列命令來編譯 imageCopyright.mof

mofcomp webadministration.mof

WMI 腳本

Mofcomp 已將 imageCopyright 架構新增至 WMI 存放庫。 藉由編寫 IIS WMI 提供者的腳本來設定 IIS 組態設定。 範例如下:

工作

開啟記事本的實例,並將下列幾行複製到其中。 將檔案儲存為SetCopyrightConfig.vbs:

Set oIIS = GetObject("winmgmts:root\WebAdministration")        
Set oSection = oIIS.Get("ImageCopyright.Path='MACHINE/WEBROOT/APPHOST/Default Web Site',Location=''")
oSection.Enabled = true
oSection.Message = "Copyright (C) IIS7 Team - Date: " & date
oSection.Color = "White"
oSection.Put_

這是連線到 IIS WMI 提供者的標準 WMI 腳本。 它會取得位於指定位置的組態區段, (「預設網站」) 並變更其值。 Put_呼叫會將變更儲存至磁片。

如果您執行腳本,它會將目前日期的著作權訊息新增至 %systemdrive%\inetpub\wwwroot\web.config 。 看一下。

接下來,新增影像著作權處理常式本身。

處理常式是一段程式碼,會在要求符合特定模式時執行,通常是副檔名。 以 結尾的要求。例如,ASP 會對應至ASP.DLL。 在 IIS 6.0 中,您必須撰寫 ISAPI 擴充功能來處理具有特定副檔名的要求。 ASP.NET 也允許處理副檔名,但只有在您先將要求對應至 ASP.NET 時。 在 IIS 中,您可以處理任意副檔名,而不需要 ASP.NET。 在我們的範例中,我們會處理具有延伸模組.JPG的要求。 以下是如何執行此動作:

建立內容目錄

建立內容目錄,例如 c:\inetpub\mypictures ,並將您選擇的一些數位圖片複製到其中。 請確定這些檔案是副檔名為.JPG的映射檔。

注意

為了簡單起見,此處所示的程式碼範例不包含非影像檔案之檔案的錯誤處理常式代碼。

在新的目錄下建立名為 App_Code 的子目錄:例如 。 c:\inetpub\mypictures\App\_Code

建立 mypictures 應用程式

您可以透過 IIS 管理主控台建立指向 的應用程式 c:\inetpub\mypictures ,但有更有趣的方式可以執行它。 透過 appcmd 建立新的應用程式。 下列命令會在具有實體路徑 c:\inetpub\mypictures 的 「預設網站」上建立名為 「mypictures」 的應用程式:

%windir%\system32\inetsrv\appcmd add app -site.name:"Default Web Site"

-path:/mypictures -physicalPath:%systemdrive%\inetpub\mypictures

因為我們想要查看複製到此目錄中的 JPG 檔案,所以請啟用瀏覽目錄。 請透過 IIS 管理主控台執行此動作,或使用更有趣的方法,並使用 appcmd。 以下是如何透過 appcmd 將瀏覽目錄設定為 true:

%windir%\system32\inetsrv\appcmd set config "Default Web Site/mypictures"

 -section:directoryBrowse -enabled:true

如果您要求 http://localhost/mypictures ,您會看到含有圖片的目錄清單。

撰寫程式碼的時間

現在,撰寫實際的影像處理常式代碼。 撰寫幾行 C# 程式碼並產生結果:使用下列程式碼作為參考,並將它儲存為 App_Code 目錄中的 imagecopyrighthandler.cs,例如 c:\inetpub\mypictures\App\_Code\imagecopyrighthandler.cs

#region Using directives
using System;
using System.Web;
using System.Drawing;
using System.Drawing.Imaging;
using Microsoft.Web.Administration;
#endregion
  
namespace IIS7Demos
{
    public class imageCopyrightHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            ConfigurationSection imageCopyrightHandlerSection = 
                WebConfigurationManager.GetSection("system.webServer/imageCopyright");
  
            HandleImage(    context,
                            (bool)imageCopyrightHandlerSection.Attributes["enabled"].Value,
                            (string)imageCopyrightHandlerSection.Attributes["message"].Value,
                            (string)imageCopyrightHandlerSection.Attributes["color"].Value                            
                        );
        }
  
        void HandleImage(   HttpContext context,
                            bool enabled,
                            string copyrightText,
                            string color
                        )           
        {
            try
            {
                string strPath = context.Request.PhysicalPath;
                if (enabled)
                {
                    Bitmap bitmap = new Bitmap(strPath);
                    // add copyright message
                    Graphics g = Graphics.FromImage(bitmap);
                    Font f = new Font("Arial", 50, GraphicsUnit.Pixel);
                    SolidBrush sb = new SolidBrush(Color.FromName(color));
                    g.DrawString(   copyrightText,
                                    f,
                                    sb,
                                    5,
                                    bitmap.Height - f.Height - 5
                                );
                    f.Dispose();
                    g.Dispose();
                    // slow, but good looking resize for large images
                    context.Response.ContentType = "image/jpeg";
                    bitmap.Save(
                                        context.Response.OutputStream,
                                        System.Drawing.Imaging.ImageFormat.Jpeg
                                     );
                    bitmap.Dispose();
                }
                else
                {
                    context.Response.WriteFile(strPath);
                }
            }
            catch (Exception e)
            {
                context.Response.Write(e.Message);
            }
        }
  
        public bool IsReusable
        {
            get { return true; }
        }
    }
}

上述程式碼會執行下列動作:

  • 讀取組態
  • 呼叫 HandleImage

HandleImage 會執行下列動作:

  • 從點陣圖建立 Graphics 物件
  • 使用設定的值建立字型物件
  • 將訊息繪製到點陣圖

若要使用 Microsoft.Web.Administration 類別,您必須新增 IIS 管理 API 元件的參考。 若要這樣做,請開啟 %systemdrive%\inetpub\mypictures\web.config 並新增下列專案:

<system.web>
    <compilation>
      <assemblies>
        <add assembly="Microsoft.Web.Administration, Version=7.0.0.0, 
Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"/>
      </assemblies>
    </compilation>
</system.web>

您也可以將處理常式編譯成元件,並將它放入 mypictures/bin。 如果您這樣做,就不需要將 Microsoft.Web.Administration 元件新增至您的 web.config 檔案。

處理常式組態

如果您要求.JPG檔案,您只需要告訴 IIS 叫用新的處理常式。 請透過 IIS 管理主控台執行此動作,或使用 appcmd:

appcmd set config "Default Web Site/mypictures/" -section:handlers 

/+[name='JPG-imageCopyrightHandler',path='*.jpg',verb='GET',type='IIS7Demos.imageCopyrightHandler']

上述 appcmd 命令只會在 /mypictures 目錄中設定新的處理常式。 因為處理常式專案位於集合中,所以您必須使用 +[] 語法。 新增專案必須新增至集合時,一律會使用此語法。 處理常式組態的元素如下:

NAME

可以是任何唯一的名稱。 名稱只會用來唯一識別處理常式。

path

告知 IIS 何時執行這個處理常式。 *.JPG會指示 IIS 針對以.JPG結尾的所有檔案執行此處理程式。 如果您使用 foo*.JPG 做為路徑,則此處理程式只會執行以 foo 開頭的 JPG 檔案。

動詞命令

逗號分隔的 HTTP 動詞命令清單,必須相符才能執行這個處理常式。 在我們的案例中,我們只想要在 GET 要求傳入時執行要求。

type

當要求相符時,應該執行的類別 Managed 型別。 它包含您App_Code目錄中的命名空間和 IHttpHandler 衍生類別。

最後一個附注

開始測試著作權映射之前,請確定執行要求的 IIS 背景工作進程會挑選您所做的架構變更。 當您將imageCopyright.xml檔案新增至架構目錄時,背景工作進程可能已經執行。 如果發生這種情況,您會在 imagecopyrightconfig.cs 中取得設定例外狀況。 撰寫本文時,作者遇到此問題,而且花費相當多的時間。

只要回收應用程式集區即可解決此問題:

appcmd recycle AppPool DefaultAppPool

程式已完成。 如果您現在要求 http://localhost/mypictures/<imageOfYourChoice>.jpg) ,您會看到著作權訊息。

選項:

  • 您可以透過 appcmd 或直接編輯web.config檔案來變更著作權訊息選項
  • 您可以將 imageCopyright 處理常式對應至其他影像類型,例如 BMP 或 GIF,方法是為不同的延伸模組新增相同的處理常式。 範例:
appcmd set config "Default Web Site/mypictures/" -section:handlers /+[name='BMP-imageCopyrightHandler',path='*.bmp',verb='GET',type='IIS7Demos.imageCopyrightHandler']

完成觸控的時間。 我們已使用幾行程式碼來擴充 IIS 核心伺服器;我們已擴充 IIS 組態系統,完全沒有程式碼,並免費取得命令列支援。 現在,若要透過 IIS 管理主控台設定 imageCopyright 處理常式。

我們會透過下列工作來執行此動作:

  • 在 Microsoft Visual Studio 或 Microsoft Visual C# Express 中建立專案,以便在 IIS 管理主控台內使用元件
  • 建立模組提供者
  • 建立讀取和設定 imageCopyright 屬性的模組。

建立專案

若要建立 InetMgr 的擴充性模組,您需要建立也稱為類別庫專案的 DLL 專案。 此 DLL 必須強式名稱,才能在 GAC (全域組件快取) 註冊,這是 IIS 管理主控台所使用的模組需求。

步驟

  1. 按一下 [開始],按一下 [程式],然後執行 Microsoft Visual Studio 2005 或 Microsoft Visual C# 2005 Express Edition。

  2. 在 [檔案] 功能表中,選取 [新增專案] 選項。

  3. 在 [新增專案] 對話方塊中,選取 [類別庫] 作為專案類型,然後輸入 imageCopyrightUI 作為專案的名稱,然後按一下 [確定]。

    [新增專案] 對話方塊的螢幕擷取畫面,其中已選取 [類別庫],並在 [名稱] 中輸入的 [著作權 U] 輸入為專案的名稱。
    圖 2:新增專案對話方塊

  4. 移除預設新增的 Class1.cs 檔案,因為我們不會使用該檔案。

  5. 使用 [專案功能表] 中的 [新增參考] 選項,將參考新增至位於 \Windows\system32\inetsrv 目錄中的Microsoft.Web.Management.dll。 這是 DLL,其中包含建立 IIS 管理主控台模組所需的所有擴充性類別。

  6. 使用 [專案功能表] 中的 [新增參考] 選項,將參考新增至位於 \Windows\system32\inetsrv 目錄中的Microsoft.Web.Administration.dll。 這是 DLL,其中包含讀取寫入 IIS 組態所需的所有組態類別。

  7. 由於我們將使用程式碼來根據 WinForms 建立 UI,因此我們也想要新增System.Windows.Forms.dll的參考;針對再次使用 [專案] 功能表中的 [新增參考] 選項,在元件清單中選取 [System.Windows.Forms.dll] 和 [System.Web.dll the.NET]。

  8. 在 InetMgr 內使用程式庫的其中一個需求,就是必須在 GAC 內註冊程式庫。 因此,我們必須確定 DLL 已強式名稱, (有時稱為「已簽署」) 。 Visual Studio 提供簡單的方法來建立新名稱,並選取專案的名稱,因此,使用 [專案] 功能表選取 imageCopyrightUI 屬性選項。

  9. 在 [簽署] 索引標籤中,檢查 [簽署元件]。

  10. 在 [建立強式名稱金鑰] 中,輸入 imageCopyrightUI 作為金鑰的名稱,然後取消核取 [使用密碼保護我的金鑰檔案] 核取方塊。 按一下 [確定]。

    [建立強式名稱金鑰] 對話方塊的螢幕擷取畫面,其中顯示 [著作權 U] 輸入為 [金鑰檔案名] 和 [密碼] 建立並確認的影像。
    圖 3:建立強式名稱對話方塊

    簽署索引標籤會顯示:

    [簽署] 索引標籤的螢幕擷取畫面,其中已選取 [選擇強式名稱金鑰檔案] 欄位中選取 [著作權 U I 點 n k]。
    圖 4:VS 專案簽署索引標籤

  11. 由於我們希望元件位於 GAC 中,因此我們會新增一些建置後事件,以便在每次編譯時自動新增至 GAC。 這會讓我們在新增新功能時,直接進行偵錯並進行變更。 針對此專案,選取 [ 建置事件] 索引 標籤,然後新增下列建置後事件命令列:

    call "%VS80COMNTOOLS%\vsvars32.bat" > NULL
    
    gacutil.exe /if "$(TargetPath)"
    

    [建置後事件] 命令列的螢幕擷取畫面,其中已填入程式碼。
    圖 5:VS 建置後事件索引標籤

    (選擇性) 如果您使用 Microsoft Visual Studio 2005 (這不適用於 Visual C# Express Edition) ,請正確設定偵錯以使用 F5 來執行程式碼。 若要這樣做,請移至專案屬性,選取 [偵錯] 索引標籤,並將其設定為啟動選擇\windows\system32\inetsrv\inetmgr.exe的外部程式

    [偵錯] 索引標籤設定為 [開始外部程式動作] 的螢幕擷取畫面。
    圖 6:偵錯索引標籤

  12. 最後,關閉專案屬性,選取 [檔案] 功能表中的 [全部儲存] 選項,然後按一下 [確定]。

    現在,使用 [建置] 功能表下的 [建置方案] 編譯專案。 這會自動建置 DLL,並將其新增至 GAC。

建立模組提供者

IIS 使用者介面與 IIS 核心伺服器和 IIS 組態系統一樣可自訂且模組化。 IIS 使用者介面是一組可移除或取代的功能模組。 每個 UI 模組的進入點都是模組提供者。 您可以在 區 <modules> 段中找到 %windir%\system32\inetsrv\Administration.config 所有模組提供者的清單。

第一個步驟是建立 imageCopyrightUI 模組提供者。

步驟

  1. 從 [專案] 功能表中選取 [新增專案] 選項。 在 [新增專案] 對話方塊中,選取 [類別] 範本,然後輸入 imageCopyrightUIModuleProvider.cs 作為檔案名。

    [新增專案] 對話方塊的螢幕擷取畫面,其中已選取 [類別範本] 和 [名稱] 欄位填入影像著作權 U I 模組提供者點 c s。
    圖 7:新增專案對話方塊

  2. 變更程式碼,使其看起來如下:

    using System;
    using System.Security;
    using Microsoft.Web.Management.Server;
        
    namespace IIS7Demos           
    {
        class imageCopyrightUIProvider : ModuleProvider
        {
            public override Type ServiceType              
            {
                get { return null; }
            }
    
            public override ModuleDefinition GetModuleDefinition(IManagementContext context)
            {
                return new ModuleDefinition(Name, typeof(imageCopyrightUI).AssemblyQualifiedName);
            }
    
            public override bool SupportsScope(ManagementScope scope)
            {
                return true;
            }
        }            
    }
    

    此程式碼會建立 ModuleProvider,其支援各種範圍 (伺服器、月臺和應用程式) ,並註冊名為 imageCopyrightUI 的用戶端模組。 為了只在應用層級顯示模組,SupportsScope 函式看起來像這樣:

    public override bool SupportsScope(ManagementScope scope)
    {
        return (scope == ManagementScope.Application) ;
    }
    

建立 UI 模組

模組是用戶端中所有擴充性物件的主要進入點。 它有一個稱為 Initialize的主要方法。 這是執行所有動作的方法。

步驟

  1. 選取 [專案] 功能表中的 [新增專案] 選項。

  2. 選取 [類別] 範本,然後輸入 imageCopyrightUI.cs 作為檔案名。 變更程式碼,使其看起來如下:

    using System;
    using System.Windows.Forms;
    using Microsoft.Web.Management.Client;
    using Microsoft.Web.Management.Server;
    
    namespace IIS7Demos
    {
        internal class imageCopyrightUI : Module
        {
            protected override void Initialize(IServiceProvider serviceProvider, ModuleInfo moduleInfo)
            {
                base.Initialize(serviceProvider, moduleInfo);
                IControlPanel controlPanel = (IControlPanel)GetService(typeof(IControlPanel));
                ModulePageInfo modulePageInfo = new ModulePageInfo(this, typeof(imageCopyrightUIPage), "Image Copyright", "Image Copyright");
                controlPanel.RegisterPage(modulePageInfo);
            }
        }              
    }
    

    在上述程式碼中,我們會在 UI 模組清單中指定專案的文字,以及當使用者按一下此文字時應該顯示的單一頁面類型。

左邊的一切都是寫入頁面本身。

建立模組頁面

在這項工作中,您會建立最基本的模組頁面。 ModulePage 是架構所提供的基類,可建立新的使用者介面。 根據您嘗試建置的案例而定,架構會提供四種不同的類別。

  • ModulePage。 此基類僅提供最基本的服務,而且完全不提供特殊的使用者介面。 InetMgr 中未包含的功能直接衍生自這個類別。
  • ModuleDialogPage。 此基類提供類似對話方塊的語意,包括工作清單中的 [套用] 和 [取消] 連結,並提供您可以覆寫的特定方法來處理此常見工作。 它也會自動處理重新整理和其他函式等事項。 衍生自此頁面的功能範例包括電腦金鑰、管理服務等。
  • ModulePropertiesPage。 此基類提供類似 Visual Studio 屬性方格的 UI,其中所有屬性都會顯示在類似階層式的方格控制項中。 此範例包括 CGI、ASP、.NET 編譯等。
  • ModuleListPage。 每當您需要顯示專案清單時,這個基類就很有用。 它包含 ListView 控制項,可讓您用來顯示設定,並提供自動搜尋、分組和檢視。 範例包括應用程式設定、模組、背景工作進程等。

步驟

  1. 從 [專案] 功能表中選取 [新增專案] 選項。

  2. 在 [新增專案] 對話方塊中,選取 [類別] 範本,然後輸入 imageCopyrightUIPage.cs 作為檔案名。 變更程式碼,使其看起來如下:

    using System;
    using System.Collections.Generic;
    using System.Windows.Forms;
    using Microsoft.Web.Management.Client.Win32;
    using Microsoft.Web.Administration;
    using Microsoft.Web.Management.Client;
    using Microsoft.Web.Management.Server;
    namespace IIS7Demos
    {
        public sealed class imageCopyrightUIPage : ModulePage
        {
            public string message;
            public bool featureenabled;
            public string color;
    
            ComboBox _colCombo = new ComboBox();
            TextBox _msgTB = new TextBox();
            CheckBox _enabledCB = new CheckBox();
            public imageCopyrightUIPage()
            {
                this.Initialize();
            }
            protected override void OnActivated(bool initialActivation)
            {
               base.OnActivated(initialActivation);
               if (initialActivation)
               {
                    ReadConfig();
                    UpdateUI();
                }
            }
    
            void UpdateUI()
            {
                _enabledCB.Checked = featureenabled;
                int n = _colCombo.FindString(color, 0);
                _colCombo.SelectedIndex = n;
                _msgTB.Text = message;
            }
    
            void Initialize()
            {
                Label crlabel = new Label();
                crlabel.Left = 50;
                crlabel.Top = 100;
                crlabel.AutoSize = true;
                crlabel.Text = "Enable Image Copyright:";
                _enabledCB.Text = "";
                _enabledCB.Left = 200;
                _enabledCB.Top = 100;
                _enabledCB.AutoSize = true;
    
                Label msglabel = new Label();
                msglabel.Left = 150;
                msglabel.Top = 130;
                msglabel.AutoSize = true;
                msglabel.Text = "Message:";
                _msgTB.Left = 200;
                _msgTB.Top = 130;
                _msgTB.Width = 200;
                _msgTB.Height = 50;
    
                Label collabel = new Label();
                collabel.Left = 160;
                collabel.Top = 160;
                collabel.AutoSize = true;
                collabel.Text = "Color:";
                _colCombo.Left = 200;
                _colCombo.Top = 160;
                _colCombo.Width = 50;
                _colCombo.Height = 90;
                _colCombo.Items.Add((object)"Yellow");
                _colCombo.Items.Add((object)"Blue");
                _colCombo.Items.Add((object)"Red");
                _colCombo.Items.Add((object)"White");
    
                Button apply = new Button();
                apply.Text = "Apply";
                apply.Click += new EventHandler(this.applyClick);
                apply.Left = 200;
                apply.AutoSize = true;
                apply.Top = 250;
    
                Controls.Add(crlabel);
                Controls.Add(_enabledCB);
                Controls.Add(collabel);
                Controls.Add(_colCombo);
                Controls.Add(msglabel);
                Controls.Add(_msgTB);
                Controls.Add(apply);
            }
    
            private void applyClick(Object sender, EventArgs e)
            {
                try
                {
                    UpdateVariables();
                    ServerManager mgr;
                    ConfigurationSection section;
                    mgr = new ServerManager();
                    Configuration config =
                    mgr.GetWebConfiguration
                    (
                           Connection.ConfigurationPath.SiteName, 
                           Connection.ConfigurationPath.ApplicationPath +
                           Connection.ConfigurationPath.FolderPath
                    );
    
                section = config.GetSection("system.webServer/imageCopyright");
                section.GetAttribute("color").Value = (object)color;
                section.GetAttribute("message").Value = (object)message;
                section.GetAttribute("enabled").Value = (object)featureenabled;
    
                mgr.CommitChanges();
    
                }
    
                catch
                {}
    
            }
    
            public void UpdateVariables()
            {
                featureenabled = _enabledCB.Checked;
                color = _colCombo.Text;
                message = _msgTB.Text;
            }
    
            public void ReadConfig()
            {
                try
                {
                    ServerManager mgr;
                    ConfigurationSection section;
                    mgr = new ServerManager();
                    Configuration config =
                    mgr.GetWebConfiguration(
                           Connection.ConfigurationPath.SiteName,
                           Connection.ConfigurationPath.ApplicationPath +
                           Connection.ConfigurationPath.FolderPath);
    
                    section = config.GetSection("system.webServer/imageCopyright");
                    color = (string)section.GetAttribute("color").Value;
                    message = (string)section.GetAttribute("message").Value;
                    featureenabled = (bool)section.GetAttribute("enabled").Value;
    
                }
    
                catch
                {}
    
            }
        }
    }
    

    雖然有許多,但此程式碼不會超過在 ModulePage 上放置幾個控制項,而且會讀取和寫入 IIS 組態存放區。

讀取設定

ReadConfig 函式會使用相同的 Microsoft.Web.Administration 介面來開啟 IIS 組態存放區。 UI 本身提供套用組態設定的範圍。

範例:

Connection.ConfigurationPath.SiteName,

Connection.ConfigurationPath.ApplicationPath+

Connection.ConfigurationPath.FolderPath

儲存組態

按一下 [套用] 按鈕 (applyClick 函式) 時,就會儲存設定。 UI 傳輸中所做的變更會儲存至區段屬性,而 區段會儲存至磁片。

section.GetAttribute("enabled").Value = (object)featureenabled;

mgr.CommitChanges();

此時,您已準備好使用 [建置方案] 從 [建置] 功能表再次編譯所有專案。 這會建置元件 imageCopyrightUI,並將它放入全域組件快取中。

模組註冊

UI 模組已建置,但我們仍然必須告訴 IIS 管理主控台載入它。 請依照下列方式執行此動作:

  • 從全域組件快取取得 UI 模組的強式名稱
  • 將強式名稱與類型新增至 IIS 管理主控台的組態檔。 這會導致 IIS 管理主控台在啟動時載入類型
  • 在 UI 模組清單中啟用模組

步驟

  1. 執行下列命令,開啟或使用現有的提升許可權命令殼層,並註冊 Visual Studio 8.0 環境變數:

    "%vs80comntools%\vsvars32.bat
    
  2. 執行 GacUtil

    GACUTIL /l imageCopyrightUI
    
  3. 在專案之後 <moduleProviders> 開啟 %windir%\system32\inetsrv\config\administration.config 並新增下列內容:

    <add name="imageCopyrightUI" type="IIS7Demos.imageCopyrightUIProvider, IIS7Demos, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3fd9bd5e992ee757"/>
    

結果

該項工作已完成。 查看結果。

開啟 IIS 管理主控台,然後流覽至 /mypictures 應用程式。

按兩下 [影像著作權] 專案。

I S Management Console 的螢幕擷取畫面,其中已選取圖片應用程式並顯示影像著作權訊息。
圖 8:影像著作權使用者介面

變更著作權訊息,按一下 [套用] 並重新整理瀏覽器。 著作權訊息已變更。 查看目錄中的web.config檔案 %systemdrive%\inetpub\mypictures ,以查看已變更的組態。

總結

IIS 可以透過之前不可能的方式擴充。 您可以使用自己的元件擴充 IIS 核心處理管線、將此元件的設定與 IIS 組態一起儲存,甚至撰寫與標準 IIS 設定並存的使用者介面外掛程式。 若要檢閱我們在上一個範例中所做的動作:

IIS 核心擴充性

我們已將影像處理常式新增至 IIS 核心,以將著作權訊息插入每個提供.JPG檔案中。 這只使用幾行 C# 程式碼來完成。 處理常式的功能是由組態驅動。 我們已將組態儲存在一般 IIS 組態檔中,applicationhost.config和web.config。我們也新增了映射的快取支援。

IIS 組態系統擴充性

我們已將映射著作權處理常式組態新增至 IIS 組態系統。 像是高度可讀和 xml 存放區、立即 API 和命令列支援、委派和分散式部署等優點免費。 我們不需要撰寫單行程式碼。

IIS 使用者介面擴充性

為了讓我們的功能能夠看見它,我們新增了 IIS 使用者介面模組。 雖然未顯示,但 IIS 使用者介面可透過 HTTPS 完全遠端。