面向 IIS 7.0 开发人员的端到端扩展性示例
作者:Saad Ladki
IIS 7 及更高版本采用完全模块化的体系结构,基于丰富的扩展性 API 构建。 这使得开发人员能够轻松添加、删除内置 IIS 组件,甚至用手工制作的组件替换内置 IIS 组件,特别适合任何给定的网站。 将代码深入插入 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 功能”。 然后打开“Internet Information Services”-“万维网服务”-“应用程序开发功能”,选中“ASP.NET”。
如果你有 Windows Server 2008 内部版本。 打开“服务器管理器”-“管理角色”并选择“Web 服务器(IIS)”。 单击“添加角色服务”。 在“应用程序开发”下,选中“ASP.NET”。
还必须安装“IIS 管理脚本和工具”,才能利用 IIS 中的 WMI 扩展性。 为此,请选择“程序”-“打开或关闭 Windows 功能”。 然后打开“Internet Information Services”-“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 配置和内容位置。 若要解决此问题,我们建议使用提升的命令提示符来阅读本文。
若要启动提升的命令提示符,请转到“开始”菜单,单击“所有程序”-“附件”。 右键单击“命令提示符”,然后单击“以管理员身份运行”。 确认提升权限提示。
场景
以下示例动态修饰我们的 Web 服务器提供的图像,并在左下角显示版权信息,如图 1 所示。
图 1:操作中的图像版权模块
我们使用托管代码来开发修饰图像的处理程序。 作为示例的一部分,我们还指定了该处理程序的配置并将其存储在 IIS 配置存储中。 最后,我们将为 IIS 管理器开发一个用户界面插件。
步骤 1 – 配置扩展性:图像版权处理程序的配置
只需将架构文件复制到 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 服务器(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
中。 请看一看。
接下来,添加图像版权处理程序本身。
步骤 2 – 核心扩展性:图像版权处理程序
处理程序是当请求匹配特定模式(通常是文件扩展名)时执行的一段代码。 例如,以 .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 创建新应用程序。 以下命令在“默认网站”上创建名为“mypictures”的应用程序,其物理路径为 c:\inetpub\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 执行以下操作:
- 从位图创建图形对象
- 使用配置的值创建字体对象
- 将消息绘制到位图中
若要使用 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 告知 IIS 对所有以 .JPG 结尾的文件执行此处理程序。 如果使用 foo*.JPG 作为路径,则此处理程序仅执行以 foo 开头的 JPG 文件。
谓词
为执行此处理程序而必须匹配的逗号分隔 http 谓词列表。 在本示例中,我们只想在 GET 请求传入时执行该请求。
type
请求匹配时应执行的类的托管类型。 它由命名空间和 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']
步骤 3 - 创建图像版权 UI 模块
差不多可以收尾了。 我们已经通过几行代码扩展了 IIS 核心服务器;无需编写任何代码就扩展了 IIS 配置系统,并免费获得了命令行支持。 现在让我们通过 IIS 管理控制台配置我们的 imageCopyright 处理程序。
通过以下任务做到这一点:
- 在 Microsoft Visual Studio 或 Microsoft Visual C# Express 中创建项目,以便可以在 IIS 管理控制台内使用程序集
- 创建模块提供程序
- 创建一个读取和设置 imageCopyright 属性的模块。
创建项目
若要为 InetMgr 创建扩展性模块,需要创建一个 DLL 项目(也称为类库项目)。 该 DLL 需要强命名,以便可以在 GAC(全局程序集缓存)中注册,这是 IIS 管理控制台使用的模块的要求。
步骤
单击“开始”,然后单击“程序”并运行 Microsoft Visual Studio 2005 或 Microsoft Visual C# 2005 Express Edition。
在“文件”菜单中,选择“新建项目”选项。
在“新建项目”对话框中,选择“类库”作为项目类型,键入 imageCopyrightUI 作为项目名称,然后单击“确定”。
图 2:“新建项目”对话框删除默认添加的文件 Class1.cs,因为我们不会使用它。
使用“项目”菜单中的“添加新引用”选项,添加对位于 \Windows\system32\inetsrv 目录中的 Microsoft.Web.Management.dll 的引用。 这是一个 DLL,其中包含为 IIS 管理控制台创建模块所需的所有扩展性类。
使用“项目”菜单中的“添加新引用”选项,添加对位于 \Windows\system32\inetsrv 目录中的 Microsoft.Web.Administration.dll 的引用。 这是一个 DLL,其中包含读取配置(用于写入 IIS 配置)所需的所有配置类。
由于我们将使用代码来创建基于 WinForms 的 UI,因此我们还需要添加对 System.Windows.Forms.dll 的引用;为此,请再次使用“项目”菜单中的“添加新引用”选项,在 .NET 程序集列表中选择 System.Windows.Forms.dll 和 System.Web.dll。
在 InetMgr 中使用库的要求之一是需要在 GAC 中将其注册。 为此,我们需要确保我们的 DLL 是强命名的(有时称为签名)。 Visual Studio 提供了一种简单方法来创建新名称并为项目选择名称,为此,请使用“项目”菜单选择“imageCopyrightUI 属性”选项。
在“签名”选项卡中,选中“对程序集进行签名”。
在“创建强名称密钥”中,键入 imageCopyrightUI 作为密钥名称,然后取消选中“使用密码保护我的密钥文件”复选框。 单击“确定”。
图 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:调试选项卡最后,关闭项目属性,选择“文件”菜单中的“全部保存”选项,然后单击“确定”。
现在,使用“生成”菜单下的“生成解决方案”编译项目。 这会自动生成 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 的主方法。 所有操作在此方法中发生。
步骤
在“项目”菜单中选择“添加新项”选项。
选择“类”模板并键入 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 控件,可用于显示设置并自动提供搜索、分组和视图。 示例包括“应用程序设置”、“模块”、“工作进程”等。
步骤
从“项目”菜单中选择“添加新项”选项。
在“添加新项”对话框中,选择“类”模板,然后键入 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 模块列表中的模块
步骤
打开或使用现有的提升的命令 shell,并通过执行以下命令注册 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 应用程序。
双击“图像版权”项。
图 8:图像版权用户界面
更改版权消息,单击“应用”并刷新浏览器。 版权消息已更改。 查看 %systemdrive%\inetpub\mypictures
目录中的 web.config 文件以查看更改后的配置。
总结
IIS 能够用以前不可能的方式进行扩展。 你可以使用自己的组件扩展 IIS 核心处理管道,将该组件的配置与 IIS 配置一起存储,甚至可以编写与标准 IIS 设置并存的用户界面插件。 回顾一下我们在前面的示例中执行的操作:
IIS 核心扩展性
我们向 IIS 核心添加了一个图像处理程序,该处理程序将版权消息插入到每个接受服务的 .JPG 文件中。 我们只编写了几行 C# 代码就做到了这一点。 处理程序的功能是由配置驱动的。 我们将配置存储到了常规 IIS 配置文件 applicationhost.config 和 web.config 中。我们还添加了对图像的缓存支持。
IIS 配置系统扩展性
我们将图像版权处理程序配置添加到了 IIS 配置系统中。 高度可读的 xml 存储、即时 API 和命令行支持、委托和分布式部署等优势都是免费的。 我们完全不用编写任何代码。
IIS 用户界面扩展性
为使我们的功能具有应有的可见性,我们添加了 IIS 用户界面模块。 尽管未显示,但完全可以通过 HTTPS 远程控制 IIS 用户界面。