IIS 7.0 開発者向けのエンド ツー エンドの機能拡張の例
作成者: Saad Ladki
IIS 7 以降は、豊富な拡張性 API に基づいて、完全にモジュール化されたアーキテクチャで構築されています。 これにより、開発者は、組み込みの IIS コンポーネントを簡単に追加、削除し、手動で作成したコンポーネントに置き換えることができます。これは、既存の Web サイトを変更する場合に特に適しています。 IIS コア パイプラインとコードを密接に統合し、以前は不可能だった方法で IIS を拡張することが、これまでにないほど簡単になりました。
いくつか例を挙げると、開発者は、数行のコードを使用するだけで、新しい認証と承認スキームを提供するモジュールまたはハンドラーを記述でき、着信要求の実行時またはセキュリティ分析を実行し、応答を検査できます。 しかし、実質的な付加価値を提供するには、これらのモジュールはプログラミング インターフェイス、コマンド ライン ツール、ユーザー インターフェイスを使用して管理できる必要があります。
このホワイト ペーパーは、カスタム要求ハンドラーを使用して IIS Web サーバーを拡張する方法のエンド ツー エンドの例です。 このハンドラーの構成に対して API とコマンド ラインのサポートを追加する方法と、IIS 管理インターフェイスにユーザー インターフェイス モジュール プラグインを記述する方法を示します。
このソリューションは、Windows Vista および Windows Server® 2008 Beta 3 でテストされています。 Windows Server 2008 の最終バージョンが利用可能になった時点で更新されます。
機能セット
- マネージド ハンドラーは著作権メッセージを画像ファイルに挿入
- 著作権メッセージ機能は構成駆動型であり、新しい IIS 構成システムを使用
- 構成はスキーマ化され、構成 API、WMI スクリプト、IIS コマンド ライン ツールからアクセス可能
- ユーザー インターフェイス拡張モジュールによって IIS ユーザー インターフェイスを介した著作権メッセージ機能の構成が可能
前提条件
このドキュメントの手順に従うには、次のソフトウェアをインストールする必要があります。
ASP.NET
Windows Vista コントロール パネルを使用して ASP.NET をインストールします。 [プログラム] - [Windows の機能をオンまたはオフにする] を選択します。 次に、[インターネット インフォメーション サービス] - [World Wide Web サービス] - [アプリケーション開発機能] を開き、[ASP.NET] をオンにします。
Windows Server 2008 ビルドがある場合、 [サーバー マネージャー] - [ロールの管理] を開き、[Web サーバー (IIS)] を選択します。 [役割サービスの追加] を選択します。 [アプリケーション開発] で [ASP.NET] をオンにします。
IIS の WMI 拡張機能を利用するには、"IIS 管理スクリプトとツール" もインストールする必要があります。 これを行うには、[プログラム] - [Windows の機能をオンまたはオフにする] を選択します。 次に、[インターネット インフォメーション サービス] - [Web 管理ツール] を開き、[IIS 管理スクリプトとツール] をオンにします。
Windows Server 2008 ビルドがある場合は、[サーバー マネージャー] - [役割] を開き、[Web サーバー (IIS)]を選択します。 [役割サービスの追加] を選択します。 [Web 管理ツール] の下の [IIS 管理スクリプトおよびツール] を確認します。
Visual C# Express Edition または Visual Studio 2005
ユーザー インターフェイス モジュールには、C# 開発ツールが必要です。 Visual Studio 2005 のコピーがない場合は、Visual Studio を無料でダウンロードできます。
ユーザー アカウント制御の問題への対処
Windows Vista ユーザー アカウント保護は、アクセス トークンから管理者特権を削除します。 既定では、IIS の構成とコンテンツの場所にはアクセスできません。 この問題を解決するには、管理者特権でのコマンド プロンプトを使用してこの記事を実行することをお勧めします。
管理者特権でのコマンド プロンプトを起動するには、[スタート] メニューの [すべてのプログラム] - [アクセサリ] を選択します。 [コマンド プロンプト] を右クリックして、[管理者として実行] を選択します。 昇格プロンプトを確認します。
シナリオ
次の例では、図 1 に示すように、Web サーバーによって提供される画像を左下隅の著作権情報で動的に装飾します。
図 1: 処理中のイメージ著作権モジュール
イメージを装飾するハンドラーを開発するため、マネージド コードを使用します。 サンプルの一部として、このハンドラーの構成を指定し、IIS 構成ストアに格納します。 最後に、IIS マネージャー用のユーザー インターフェイス プラグインを開発します。
手順 1 - 構成の拡張性: イメージ著作権ハンドラーの構成
IIS 構成ストアは、スキーマ ファイルを IIS スキーマ ディレクトリにコピーするだけで拡張できます。 スキーマは、新しい構成セクションの名前とその属性、型、既定値を宣言します。 この例では、imageCopyright という名前の新しい構成セクションを宣言します。 system.webServer 構成グループ内に存在します。 そのプロパティは次のとおりです。
- imageCopyright 機能を有効または無効にするブール型フラグ
- 著作権メッセージを含む文字列属性
- 著作権メッセージの色を指定する color 属性
スキーマ宣言
次のスキーマ定義を %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 構成のスクリプト実行可能化
Note
WMI スクリプトで imageCopyright ハンドラー構成を使用できるようにするのは省略可能です。 残りの手順に影響せずに、"手順 2 - コア機能拡張: イメージ著作権ハンドラー" に直接進めます。
WMI スクリプトで imageCopyright ハンドラー構成を使用できるようにするには、次の手順を実行します。
- IIS WMI サポートのインストール
- imageCopyright.mof ファイルの作成
- imageCopyright.mof ファイルの webadministration.mof への追加と WMI スキーマ ファイルのコンパイル
- スクリプトの記述と実行
IIS WMI サポートのインストール
IIS の既定のインストールには、WMI スクリプト コンポーネントは含まれません。 それらを追加する必要があります。
Vista クライアント SKU への WMI サポートのインストール
Windows Vista コントロール パネルから "IIS 管理スクリプトとツール" をインストールします。 [プログラム] - [Windows の機能をオンまたはオフにする] を選択します。 次に、[インターネット インフォメーション サービス] - [Web 管理ツール] を開き、[IIS 管理スクリプトとツール] をオンにします。
Windows Server 2008 SKU への WMI サポートのインストール
Windows Server 2008 ビルドがある場合は、[サーバー マネージャー] - [役割] を開き、[Web サーバー (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 は、WMI リポジトリに imageCopyright スキーマを追加しました。 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 スクリプトです。 指定した場所 ("既定の Web サイト") にある構成セクションを取得し、その値を変更します。 Put_ 呼び出しによって、変更がディスクに保存されます。
スクリプトを実行すると、現在の日付を含む著作権メッセージが %systemdrive%\inetpub\wwwroot\web.config
に追加されます。 見てみましょう。
次に、イメージ著作権ハンドラー自体を追加します。
手順 2 - コア機能拡張: イメージ著作権ハンドラー
ハンドラーは、要求が特定のパターン (通常はファイル拡張子) と一致したときに実行されるコードの一部です。 たとえば、.ASP で終わる要求は、ASP.DLL にマップされます。 IIS 6.0 では、特定のファイル拡張子を持つ要求を処理するために、ISAPI 拡張を記述する必要がありました。 ASP.NET にはファイル拡張子の処理も許可されていますが、最初に要求を ASP.NET にマップした場合にのみできます。 IIS では、ASP.NET を使用せずに任意のファイル拡張子を処理できます。 この例では、.JPG 拡張子を持つ要求を処理します。 これを行う方法を次に示します。
コンテンツ ディレクトリの作成
たとえば、c:\inetpub\mypictures
などのコンテンツ ディレクトリを作成し、任意のデジタル画像をコピーここにします。 これらのファイルが .JPG 拡張子を持つイメージ ファイルであることを確認します。
Note
わかりやすくするために、ここで示すコード例には、イメージ ファイルではないファイルのエラー処理コードは含まれていません。
新しいディレクトリの下に、c:\inetpub\mypictures\App\_Code
などの App_Code と呼ばれるサブディレクトリを作成します。
mypictures アプリケーションの作成
IIS 管理コンソールを使用して c:\inetpub\mypictures
をポイントするアプリケーションを作成できますが、これを行うにはより面白い方法があります。 appcmd を使用して新しいアプリケーションを作成します。 次のコマンドは、物理パス c:\inetpub\mypictures
を持つ "既定の Web サイト" に "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# コードを記述すると、結果が得られます。次のコードを参照として使用し、c:\inetpub\mypictures\App\_Code\imagecopyrighthandler.cs
などの 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 ディレクトリでのみ新しいハンドラーを構成します。 ハンドラー エントリはコレクション内にあるため、+[] 構文を使用する必要があります。 この構文は、add 要素をコレクションに追加する必要がある場合に常に使用されます。 ハンドラー構成の要素は次のとおりです。
name
任意の一意の名前を指定できます。 この名前は、ハンドラーを一意に識別するためにのみ使用されます。
path
このハンドラーを実行するタイミングを IIS に指示します。 *.JPG は、.JPG で終わるすべてのファイルに対してこのハンドラーを実行するように IIS に指示します。 foo*.JPG をパスとして使用すると、foo で始まる JPG ファイルのみがこのハンドラーによって実行されます。
verb
このハンドラーを実行するために一致する必要がある http 動詞の一覧をコンマ区切りで指定します。 ここでは、GET 要求を受信したときにのみ、要求を実行することにします。
type
このクラスのマネージド型は、要求が一致したときにのみ実行されるようにします。 これは、App_Code ディレクトリ内の名前空間と IHttpHandler 派生クラスで構成されます。
もう 1 つ注意すること
著作権で保護されたイメージのテストを開始する前に、要求を実行する 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']
手順 3 - イメージ著作権 UI モジュールの作成
次は、最後の仕上げに進みましょう。 これまでに、IIS コア サーバーを数行のコードを追加して拡張しました。また、コードをまったく追加せずに IIS 構成システムを拡張し、コマンドラインのサポートを無料で受けました。 次に、IIS 管理コンソールを使用して imageCopyright ハンドラーを構成します。
これを行うには、次のタスクを実行します。
- アセンブリを IIS 管理コンソール内で使用できるようにするための Microsoft Visual Studio または Microsoft Visual C# Express でのプロジェクトの作成
- モジュール プロバイダーの作成
- imageCopyright プロパティの読み取りと設定を行うモジュールの作成。
プロジェクトの作成
InetMgr の機能拡張モジュールを作成するには、クラス ライブラリ プロジェクトとも呼ばれる DLL プロジェクトを作成する必要があります。 この DLL は、IIS 管理コンソールで使用されるモジュールの要件である GAC (グローバル アセンブリ キャッシュ) に登録できるように、厳密な名前を付ける必要があります。
手順
[スタート] を選択し、[プログラム] を選択して、Microsoft Visual Studio 2005 または Microsoft Visual C# 2005 Express Edition を実行します。
[ファイル] メニューで、[新しいプロジェクト] オプションを選択します。
[新しいプロジェクト] ダイアログで、プロジェクトの種類として [クラス ライブラリ] を選択し、プロジェクトの名前として「imageCopyrightUI」と入力し、[OK] を選択します。
図 2: [新しいプロジェクト] ダイアログ既定で追加されたファイル Class1.cs を削除します。このファイルは使用されないためです。
[プロジェクト] メニューの [新しい参照の追加] オプションを使用して、\Windows\system32\inetsrv ディレクトリにある Microsoft.Web.Management.dll への参照を追加します。 これは、IIS 管理コンソールのモジュールを作成するために必要なすべての拡張クラスを含む DLL です。
[プロジェクト] メニューの [新しい参照の追加] オプションを使用して、\Windows\system32\inetsrv ディレクトリにある Microsoft.Web.Administration.dll への参照を追加します。 これは、IIS 構成を記述する構成の読み取りに必要なすべての構成クラスを含む DLL です。
WinForms に基づいて UI を作成するコードを使用するため、System.Windows.Forms.dll への参照も追加する必要があります。その場合は、[プロジェクト] メニューの [新しい参照の追加] オプションを使用して、アセンブリの .NET 一覧で System.Windows.Forms.dll と System.Web.dll を選択します。
InetMgr 内でライブラリを使用するための要件の 1 つは、GAC 内に登録する必要があるということです。 そのためには、DLL に厳密な名前が付けられている (署名済みとも呼ばれることもあります) ことを確認する必要があります。 Visual Studio には、新しい名前を作成し、プロジェクト用に名前を選択する簡単な方法が用意されているため、[プロジェクト] メニューを使用して imageCopyrightUI プロパティのオプションを選択します。
[署名] タブで、[アセンブリに署名する] をオンにします。
[厳密な名前キーの作成] で、キーの名前として「imageCopyrightUI」を入力し、[キー ファイルをパスワードで保護する] チェック ボックスをオフにします。 OK をクリックします。
図 3: 厳密な名前の作成ダイアログ[署名] タブに次の情報が表示されます。
図 4: VS プロジェクト署名タブアセンブリを 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: [デバッグ] タブ最後に、プロジェクトのプロパティを閉じ、[ファイル] メニューの [すべて保存] オプションを選択し、[OK] を選択します。
次に、[ビルド] メニューの [ソリューションのビルド] を使用してプロジェクトをコンパイルします。 これにより、DLL が自動的にビルドされ、GAC に追加されます。
モジュール プロバイダーの作成
IIS ユーザー インターフェイスは、IIS コア サーバーおよび IIS 構成システムと同様にカスタマイズ可能であり、モジュール化できます。 IIS ユーザー インターフェイスは、削除または置換できる機能モジュールのセットです。 各 UI モジュールのエントリ ポイントはモジュール プロバイダーです。 すべてのモジュール プロバイダーの一覧は、<modules>
セクションの %windir%\system32\inetsrv\Administration.config
にあります。
最初の手順として、imageCopyrightUI モジュール プロバイダーを作成します。
手順
[プロジェクト] メニューから [新しい項目の追加] オプションを選択します。 [新しい項目の追加] ダイアログで、クラス テンプレートを選択し、ファイルの名前として「imageCopyrightUIModuleProvider.cs」と入力します。
図 7: [新しい項目の追加] ダイアログ次のようにコードを変更します。
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 つのメイン メソッドがあります。 これは、すべてのアクションが実行されるメソッドです。
手順
[プロジェクト] メニューの [新しい項目の追加] オプションを選択します。
クラス テンプレートを選択し、ファイル名として 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 モジュールの一覧のエントリのテキストと、ユーザーがこのテキストを選択したときに表示される 1 つのページの種類を指定します。
あと残っているのは、ページ自体を書き込むことです。
[モジュール] ページの作成
このタスクでは、最も基本的なモジュール ページを作成します。 ModulePage は、新しいユーザー インターフェイスを作成するためにフレームワークによって提供される基底クラスです。 ビルドするシナリオに応じて、フレームワークによって提供される 4 つの異なるクラスが役立ちます。
- ModulePage。 この基底クラスは、最も基本的なサービスのみを提供し、特別なユーザー インターフェイスをまったく提供しません。 InetMgr に含まれる機能は、このクラスから直接派生しません。
- ModuleDialogPage。 この基底クラスは、タスク リストの [適用] リンクと [キャンセル] リンクを含むダイアログと同様のセマンティクスを提供し、この一般的なタスクを処理するためにオーバーライドできる特定のメソッドを提供します。 また、Refresh などの機能も自動的に処理されます。 このページから派生する機能のサンプルには、マシン キー、管理サービスなどがあります。
- ModulePropertiesPage。 この基底クラスは、すべてのプロパティが階層グリッドのようなコントロールに表示される Visual Studio プロパティ グリッドに似た UI を提供します。 このサンプルには、CGI、ASP、.NET コンパイルなどがあります。
- ModuleListPage。 この基底クラスは、項目の一覧を表示する必要がある場合に便利です。 これには、設定の表示に使用できる ListView コントロールが含まれており、検索、グループ化、ビューを自動的に提供します。 サンプルには、アプリケーション設定、モジュール、ワーカー プロセスなどがあります。
手順
[プロジェクト] メニューから [新しい項目の追加] オプションを選択します。
[新しい項目の追加] ダイアログで、クラス テンプレートを選択し、ファイルの名前として「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 に 2 つのコントロールを配置し、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 モジュールの一覧でのモジュールの有効化
手順
既存の管理者特権コマンド シェルを開くか使用し、次のコマンドを実行して Visual Studio 8.0 環境変数を登録します。
"%vs80comntools%\vsvars32.bat
GacUtil の実行
GACUTIL /l imageCopyrightUI
%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: イメージ著作権のユーザー インターフェイス
著作権メッセージを変更し、[適用] を選択してブラウザーを更新します。 著作権メッセージが変更されました。 %systemdrive%\inetpub\mypictures
ディレクトリ内の web.config ファイルを調べ、変更された構成を確認します。
まとめ
IIS は、以前は不可能だった方法で拡張できます。 独自のコンポーネントを使用して IIS コア処理パイプラインを拡張し、このコンポーネントの構成を IIS 構成と共に格納し、標準の IIS 設定と並行して存在するユーザー インターフェイス プラグインを記述することもできます。 次は、前の例での処理内容をおさらいします。
IIS Core の機能拡張
サービスを受ける各 .JPG ファイルに著作権メッセージを挿入する IIS コアに、イメージ ハンドラーを追加しました。 これは、わずか数行の C# コードで実現されました。 ハンドラーの機能は、構成駆動型でした。 構成は、通常の IIS 構成ファイルである applicationhost.config と web.config に格納しました。また、イメージのキャッシュ サポートも追加しました。
IIS 構成システムの拡張性
イメージ著作権ハンドラーの構成を IIS 構成システムに追加しました。 高度に読み取り可能で XML 格納可能、インスタント API とコマンド ラインのサポート、委任、分散デプロイなどの利点が無料で提供されました。 コードは 1 行も記述する必要はありませんでした。
IIS ユーザー インターフェイスの拡張性
機能に値する可視性を提供するために、IIS ユーザー インターフェイス モジュールを追加しました。 ここでは示されていませんが、IIS ユーザー インターフェイスは、HTTPS 経由で完全にリモート処理できます。