IIS 7 開発者向けのエンドツーエンドの拡張性の例

公開日: 2007 年 11 月 24 日 (作業者: saad (英語))

更新日: 2008 年 11 月 4 日 (作業者: saad (英語))

はじめに

IIS 7 は、豊富な拡張 API を基盤とする、完全にモジュール化されたアーキテクチャによって構築されています。これにより、開発者は容易にコンポーネントを追加、削除したり、IIS 7 の組み込みコンポーネントを、特定の Web サイト専用に開発したコンポーネントに置き換えたりすることができます。これまでは、IIS コア パイプラインにコードをプラグインするのは容易なことではなく、このような方法で IIS を拡張することは不可能でした。

たとえば、開発者は、数行のコードでモジュールやハンドラーを作成して、新しい認証や承認のスキームを提供したり、受信要求のランタイム分析やセキュリティ分析を実行したり、応答を検証したりすることができます。しかし、本当の意味での付加価値を提供するには、これらのモジュールをプログラミング インターフェイス、コマンド ライン ツール、およびユーザー インターフェイスを通じて管理できなければなりません。

このホワイト ペーパーでは、カスタムの要求ハンドラーにより IIS 7 Web サーバーをエンドツーエンドで拡張する方法の例を紹介します。この例では、API や コマンド ラインによってこのハンドラーの構成をサポートできるようにする方法、および IIS 管理インターフェイスにプラグイン可能なユーザー インターフェイス モジュールを作成する方法を示します。

このソリューションは、Windows Vista および Windows Server® 2008 Beta 3 でテスト済みです。Windows Server 2008 の最終バージョンが提供された時点で更新される予定です。

機能セット

  • マネージ ハンドラーにより、画像ファイルに著作権メッセージを挿入できます。
  • 著作権メッセージ機能は、構成駆動型で、新しい IIS 7 構成システムを使用します。
  • 構成はスキーマ化して、構成 API、WMI スクリプト、および IIS コマンド ライン ツールからアクセスできます。
  • ユーザー インターフェイス拡張モジュールによって、IIS 7 ユーザー インターフェイスから著作権メッセージ機能を構成できるようになります。

必要条件

このドキュメントの手順を実行するには、以下のソフトウェアをインストールする必要があります。

ASP.NET

Windows Vista のコントロール パネルから ASP.NET をインストールします。[プログラム]、[Windows の機能の有効化または無効化] の順にクリックします。[Internet Information Services]、[World Wide Web サービス]、[アプリケーション開発機能] の順に開き、[ASP.NET] チェック ボックスをオンにします。

Windows Server 2008 の場合は、[サーバー マネージャー]、[役割の管理] の順に開き、[Web サーバー (IIS)] をクリックします。[役割サービスの追加] をクリックします。[アプリケーション開発] の [ASP.NET] チェック ボックスをオンにします。

IIS 7 の WMI 拡張機能を活用するには、IIS 管理スクリプトおよび IIS 管理ツールもインストールする必要があります。インストールするには、[プログラム]、[Windows の機能の有効化または無効化] の順にクリックします。次に、[Internet Information Services]、[Web 管理ツール] の順に開き、[IIS 管理スクリプトおよびツール] チェック ボックスをオンにします。

Windows Server 2008 の場合は、[サーバー マネージャー]、[役割] の順に開き、[Web サーバー (IIS)] をクリックします。[役割サービスの追加] をクリックします。[Web 管理ツール] の [IIS 管理スクリプトおよびツール] チェック ボックスをオンにします。

Visual C# Express Edition または Visual Studio 2008

ユーザー インターフェイス モジュールの場合、C# 開発ツールが必要です。Visual Studio 2008 がない場合でも、無料で Visual C# Express をダウンロードできます。

ユーザー アカウント制御の問題への対処

Windows Vista のユーザー アカウント保護によって、アクセス トークンから管理者特権が削除されるため、既定では、IIS の構成およびコンテンツの保存場所にアクセスできません。この問題を修正するために、権限を昇格したコマンド プロンプトを使用してこの記事の手順を実行することをお勧めします。

権限を昇格したコマンド プロンプトを起動するには、[スタート] ボタンをクリックし、[すべてのプログラム]、[アクセサリ] の順にクリックします。[コマンド プロンプト] を右クリックし、[管理者として実行] をクリックします。確認メッセージが表示されたら、昇格することを確定します。

シナリオ

次の例では、図 1 に示すように、Web サーバーによって提供される画像の左下隅に著作権情報を動的に追加しています。

Ff453971.168_Fig1(ja-jp,TechNet.10).png

図 1: 画像の著作権モジュールの実例

画像を装飾するハンドラーの作成にはマネージ コードを使用します。サンプルの一部として、このハンドラーの構成を指定し、IIS 7 構成ストアに保存します。最後に、IIS マネージャーのユーザー インターフェイス プラグインを作成します。

手順 1 - 構成の拡張性: 画像の著作権ハンドラーの構成

IIS 7 構成ストアは、IIS 7 スキーマ ディレクトリにスキーマ ファイルをコピーするだけで拡張できます。スキーマによって、新しい構成セクションの名前と、その属性、種類、および既定値を宣言します。この例では、imageCopyright という新しい構成セクションを宣言します。この構成セクションは、system.webServer 構成グループ内に作成します。次のようなプロパティがあります。

  • imageCopyright 機能を有効または無効にするブール フラグ
  • 著作権メッセージが格納されている文字列属性
  • 著作権メッセージの色を指定する色属性

スキーマ宣言

次のスキーマ定義を、imagecopyright.xml という名前で、%windir%\system32\inetsrv\config\schema に保存します。

<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 で直接設定することができます。実際に試してみてください。コマンド シェルを開き、次のように入力します。

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

出力結果に、構成セクションが認識されたことが示されます。また、その既定の構成が表示されます。

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

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 7 WMI サポートのインストール
  • imageCopyright.mof ファイルの作成
  • webadministration.mof への imageCopyright.mof ファイルの追加および WMI スキーマ ファイルのコンパイル
  • スクリプトの作成と実行

IIS 7 WMI サポートのインストール

IIS 7 の既定のインストールには、WMI スクリプト コンポーネントは含まれていません。これらのコンポーネントを追加する必要があります。

Windows Vista クライアント SKU への WMI サポートのインストール

Windows Vista のコントロール パネルで IIS 管理スクリプトおよびツールをインストールします。[プログラム]、[Windows の機能の有効化または無効化] の順にクリックします。次に、[Internet Information Services]、[Web 管理ツール] の順に開き、[IIS 管理スクリプトおよびツール] チェック ボックスをオンにします。

Windows Server 2008 SKU への WMI サポートのインストール

Windows Server 2008 の場合は、[サーバー マネージャー]、[役割] の順に開き、[Web サーバー (IIS)] をクリックします。[役割サービスの追加] をクリックします。[管理ツール] の [IIS 管理スクリプトおよびツール] チェック ボックスをオンにします。

imageCopyright.mof ファイルの作成

WMI プロパティのスキーマ宣言は、前の手順の IIS 7 プロパティのスキーマ宣言とよく似ています。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 imageCopyright.mof

WMI スクリプト

Mofcomp によって、imageCopyright スキーマが WMI リポジトリに追加されました。IIS 7 WMI プロバイダーをスクリプト化することによって、IIS 7 構成設定を設定します。次に例を示します。

タスク

メモ帳を開き、以下の行をコピーして貼り付けます。このファイルを 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 7 WMI プロバイダーに接続する標準的な WMI スクリプトです。このスクリプトは、指定された場所 ("Default Web Site") から構成セクションを取得し、その値を変更します。Put_ の呼び出しによって変更内容をディスクに保存します。

スクリプトを実行すると、現在の日付を含む著作権メッセージが %systemdrive%\inetpub\wwwroot\web.config に追加されます。確認してみてください。

次に、画像の著作権ハンドラー自体を追加します。

手順 2 - コアの拡張性: 画像の著作権ハンドラー

ハンドラーは、要求が特定のパターン (通常はファイル拡張子) に一致する場合に実行されるコードです。たとえば、.ASP で終わる要求は ASP.DLL にマップされます。IIS 6.0 では、特定のファイル拡張子を持つ要求を処理する ISAPI 拡張機能を作成する必要がありました。ASP.NET でも、ファイル拡張子に応じて要求を処理することは可能でしたが、要求が最初に ASP.NET にマップされている場合のみに限られていました。IIS 7 では、ASP.NET を使用せずに任意のファイル拡張子を処理できます。この例では、.JPG という拡張子を持つ要求を処理します。手順は次のとおりです。

コンテンツ ディレクトリの作成

コンテンツ ディレクトリ (例: c:\inetpub\mypictures) を作成し、選択したデジタル写真をこのディレクトリにコピーします。この際、デジタル写真は拡張子が .JPG の画像ファイルを使用してください。

: 説明を簡単にするために、このコード例には、画像ファイルではないファイルのエラー処理コードは含まれていません。

新しく作成したコンテンツ ディレクトリの下に App_Code という名前のサブディレクトリ (例: c:\inetpub\mypictures\App_Code) を作成します。

mypictures アプリケーションの作成

IIS 管理コンソールを使って c:\inetpub\mypictures を指すアプリケーションを作成できますが、もっとおもしろい方法があります。appcmd によって新しいアプリケーションを作成します。次のコマンドは、物理パスが c:\inetpub\mypictures である "Default Web Site" に "mypictures" という名前のアプリケーションを作成します。

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

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

      

ディレクトリの参照を有効にして、このディレクトリにコピーした JPG ファイルを表示できるようにします。この作業は IIS 管理コンソールで行うことも、appcmd を使用して行うこともできます。appcmd を使用してディレクトリ参照を有効に設定する方法を以下に示します。

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

 -section:directoryBrowse -enabled:true

https://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 7 Administration 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 7 に指示するだけです。これには、IIS 管理コンソールを使用するか、次に示すように appcmd を使用します。

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

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

この appcmd コマンドは、/mypictures ディレクトリ内でのみ新しいハンドラーを構成します。ハンドラー エントリはコレクション内にあるので、+[] 構文を使用する必要があります。この構文は、add 要素をコレクションに追加する場合に使用します。ハンドラー構成の要素は次のとおりです。

name

任意の一意の名前を指定できます。この名前は、ハンドラーを一意に識別するためにのみ使用します。

path

このハンドラーをいつ実行するかを指定します。*.JPG と指定すると、名前の末尾が .JPG であるすべてのファイルについて、このハンドラーが実行されます。foo*.JPG と指定すると、名前が foo で始まる JPG ファイルのみがこのハンドラーで処理されます。

verb

ハンドラーの実行を許可する HTTP 動詞のコンマ区切りのリストです。 この例では、GET 要求を受信した場合にのみ要求を処理します。

type

要求が一致しているときに実行するクラスのマネージ型です。この型は、App_Code ディレクトリ内の IHttpHandler 派生クラスと名前空間で構成されます。

最後の注意事項

著作権表示付きの画像の検証を開始する前に、要求を処理する IIS 7 ワーカー プロセスに、スキーマの変更が反映されていることを確認します。スキーマ ディレクトリに imageCopyright.xml ファイルを追加したときに、既にこのワーカー プロセスが実行されている可能性があります。この場合、imagecopyrightconfig.cs で構成の例外が発生します。筆者自身もこの記事を執筆する際にこの問題に直面し、原因の究明に時間を費やしました。

この問題は、アプリケーション プールをリサイクルするだけで解決できます。

appcmd recycle AppPool DefaultAppPool

これで、この手順は完了です。https://localhost/mypictures/<imageOfYourChoice.jpg>を要求すると、著作権メッセージが表示されていることを確認できます。

オプション:

  • 著作権メッセージのオプションは、appcmd で変更するか、直接 web.config ファイルを編集して変更します。
  • 他の画像形式 (BMP や GIF など) に imageCopyright ハンドラーをマップするには、その拡張子への対応を追加します。以下に例を示します。
appcmd set config "Default Web Site/mypictures/" -section:handlers /+[name='BMP-imageCopyrightHandler',path='*.bmp',verb='GET',type='IIS7Demos.imageCopyrightHandler']

手順 3 - 画像の著作権 UI モジュールの作成

これが最後の手順になります。数行のコードで IIS 7 コア サーバーを拡張し、コードをまったく使用せずに IIS 7 構成システムを拡張し、無償でコマンド ラインのサポートを取得しました。ここでは、IIS 管理コンソールを使用して、imageCopyright ハンドラーを構成します。

これには、以下のタスクを実行します。

  • Microsoft Visual Studio または Microsoft Visual C# Express でプロジェクトを作成し、IIS 管理コンソール内でアセンブリを使用できるようにする
  • モジュール プロバイダーを作成する
  • imageCopyright のプロパティの読み取りおよび設定を行うモジュールを作成する

プロジェクトの作成

InetMgr の拡張機能モジュールを作成するには、DLL プロジェクト (クラス ライブラリ プロジェクトとも呼ばれる) を作成する必要があります。この DLL には厳密な名前を付けて、IIS 管理コンソールで使用するモジュールの要件である GAC (グローバル アセンブリ キャッシュ) に登録できるようにする必要があります。

手順

  1. [スタート] ボタン、[プログラム] の順にクリックし、[Microsoft Visual Studio 2008] または [Microsoft Visual C# 2008 Express Edition] をクリックして実行します。
  2. [ファイル] メニューの [新しいプロジェクト] をクリックします。
  3. [新しいプロジェクト] ダイアログ ボックスで、プロジェクトの種類として [クラス ライブラリ] をクリックし、プロジェクトの名前として「imageCopyrightUI」と入力し、[OK] をクリックします。

Ff453971.168_Fig2(ja-jp,TechNet.10).png

図 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 への参照も追加する必要があります。これには、再び [プロジェクト] メニューの [新しい参照の追加] をクリックして、アセンブリの .NET のリストで System.Windows.Forms.dll と System.Web.dll をクリックします。

   8. InetMgr の内部で使用されるライブラリの要件の 1 つとして、ライブラリは GAC に登録されている必要があります。そのために、DLL には厳密な名前が付けられている ("署名されている" とも言う) 必要があります。Visual Studio には、簡単に新しい名前を作成し、その名前をプロジェクトに設定する方法が用意されています。この機能を使用するには、[プロジェクト] メニューの [imageCopyrightUI のプロパティ] をクリックします。

  9.[署名] タブの [アセンブリの署名] チェック ボックスをオン

 

 10.[厳密な名前のキーファイルを選択してください] ドロップダウンリストから “<新規作成...>” を選択します。

 11.[厳密な名前のキーファイルを選択してください] ドロップダウンリストから “<新規作成...>” を選択します。

Ff453971.168_Fig3(ja-jp,TechNet.10).png 

図 3: [厳密な名前キーの作成] ダイアログ ボックスーの作成] ダイアログ ボックス

[署名] タブは次のように表示されます。

Ff453971.168_extensibility-figure1(ja-jp,TechNet.10).jpg

図 4: Visual Studio プロジェクトの [署名] タブ

   11. アセンブリを GAC に登録する必要があるので、コンパイルのたびに自動的にアセンブリが GAC に追加されるように、ビルド後のイベントをいくつか追加します。これによって、新しい機能を追加する際に、簡単にデバッグや変更を行うことができます。これには、[ビルド イベント] タブをクリックし、ビルド後に実行するコマンド ラインとして以下を追加します。

call "%VS80COMNTOOLS%\vsvars32.bat" > NULL

    gacutil.exe /if "$(TargetPath)" 

※ ) 環境によっては、この設定によりコンパイルエラーが発生する場合があります。その場合は、同設定を削除し、コンパイルを完了します。その後、コマンドラインより手動で以下のコマンドの実行を行います。

gacutil.exe /if 生成されたアセンブリ (IIS7Demos.dll) までのフルパス

Ff453971.168_Fig5(ja-jp,TechNet.10).png 

図 5: Visual Studio の [ビルド イベント] タブ の [ビルド イベント] タブ

Microsoft Visual Studio 2008 を使用している場合 (この手順は Visual C# Express Edition では動作しません)、デバッグ機能を正しくセットアップして、F5 キーでコードを実行できるようにします。これには、プロジェクトのプロパティを開き、[デバッグ] タブをクリックし、[外部プログラムの開始] をクリックして、\windows\system32\inetsrv\inetmgr.exe を選択します。

Ff453971.168_Fig6(ja-jp,TechNet.10).png

図 6: [デバッグ] タブ">図 6: [デバッグ] タブ

   12. 最後に、プロジェクトのプロパティを閉じ、[ファイル] メニューの [すべてを保存] をクリックし、[OK] をクリックします。

次に、[ビルド] メニューの [ソリューションのビルド] をクリックしてプロジェクトをコンパイルします。DLL が自動的にビルドされ、GAC に追加されます。

モジュール プロバイダーの作成

IIS 7 のユーザー インターフェイスも、コア サーバーや構成システムと同様にカスタマイズが可能で、モジュール化されています。IIS 7 のユーザー インターフェイスは、機能モジュールのセットで、削除や置換が可能です。各 UI モジュールのエントリ ポイントはモジュール プロバイダーです。すべてのモジュール プロバイダーの一覧は、%windir%\system32\inetsrv\Administration.config の <modules> セクションに記述されています。

最初の手順として、imageCopyrightUI モジュール プロバイダーを作成します。

手順

   1. [プロジェクト] メニューの [新しい項目の追加] をクリックします。[新しい項目の追加] ダイアログ ボックスで、[クラス] テンプレートをクリックし、ファイルの名前として「imageCopyrightUIModuleProvider.cs」と入力します。

Ff453971.168_Fig7(ja-jp,TechNet.10).png 

図 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 は、フレームワークで用意されている、新しいユーザー インターフェイスを作成するための基本クラスです。フレームワークでは 4 種類のクラスが用意されており、構築したいページに応じて使い分けることができます。

  • 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 7 構成ストアの読み書きを行っているだけです。

構成の読み取り

ReadConfig 関数は同じ Microsoft.Web.Administration インターフェイスを使用して、IIS 7 構成ストアを開きます。UI 自体によって、構成設定が適用されるスコープが提供されます。

以下に例を示します。

Connection.ConfigurationPath.SiteName,

Connection.ConfigurationPath.ApplicationPath+

Connection.ConfigurationPath.FolderPath

構成の保存

構成は、[Apply] ボタンをクリックする (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 s%\vsvars32.bat

  2. GacUtil を実行します。       

    GACUTIL /l imageCopyrightUI

  3. %windir%\system32\inetsrv\config\administration.config を開き、<moduleProviders> エントリの直後に次の行を追加します。

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

結果

これで作業は完了しました。結果を確認してください。

IIS 管理コンソールを開き、/mypictures アプリケーションに移動します。

[Image Copyright] のエントリをダブルクリックします。次のページが表示されます。

図 8: IIS マネージャー

Ff453971.168_Fig9(ja-jp,TechNet.10).png 

図 9: Image Copyright のユーザー インターフェイス

著作権メッセージを変更し、[Apply] をクリックしてブラウザーの表示を更新します。著作権メッセージが変更されます。%systemdrive%\inetpub\mypictures ディレクトリにある web.config ファイルで、構成が変更されていることを確認できます。

まとめ

IIS 7 では、これまでは不可能だった方法で拡張できるようになりました。IIS 7 コア処理パイプラインを独自のコンポーネントで拡張したり、このコンポーネントの構成を IIS 7 の構成といっしょに保存したり、標準的な IIS 7 の設定と共存可能なユーザー インターフェイス プラグインを作成することもできます。前の例で行った作業をまとめると、次のようになります。

IIS 7 コアの拡張

表示される .JPG ファイルに著作権メッセージを挿入する画像ハンドラーを IIS 7 コアに追加しました。これは、C# コードをほんの数行記述するだけで実現できました。ハンドラーの機能は構成によって決まります。構成は、通常の IIS 7 の構成ファイルである applicationhost.config と web.config に保存しました。また、画像のキャッシュのサポートも追加しました。

IIS 7 構成システムの拡張

画像の著作権ハンドラーの構成を IIS 7 構成システムに追加しました。可読性の高い XML ストア、API やコマンド ラインのサポート、委任や分散展開などを無償で利用できます。コードは 1 行も記述する必要がありません。

IIS 7 ユーザー インターフェイスの拡張

作成した機能を表示するため、IIS ユーザー インターフェイス モジュールを追加しました。ここでは説明しませんでしたが、この IIS ユーザー インターフェイスは HTTPS を介してリモート処理が可能です。