在 IIS 控制台中配置 32 位托管处理程序时出错

阿里云服务器

本文帮助您解决尝试通过 Internet 信息服务 (IIS) 管理器向网站或 Web 应用程序配置添加托管模块或处理程序时出现的问题。

原始产品版本:   Internet Information Services 8.0、Internet Information Services 8.5
原始 KB 编号:   3194551

症状

请考虑以下情形:

您想要将托管处理程序或托管模块添加到 IIS Web 服务器上的某个 IIS 网站或 Web 应用程序的配置中。

为此,请在 IIS 管理器控制台中选择目标网站或 Web 应用程序,单击处理程序映射或模块映射图标,然后单击控制台右侧窗格中的添加托管处理程序或添加托管模块链接。

如果服务器运行的是 64 位操作系统,并且包含您尝试添加到处理程序或模块列表中的托管处理程序或托管模块实现的 .NET 程序集是编译为仅针对 32 位环境的程序集,您会从 IIS 管理器控制台收到以下错误消息:

执行此操作时出错
详细信息:在应用程序启动前初始化阶段无法调用此方法

原因

当您尝试添加托管处理程序或托管模块时,IIS 管理器控制台会构建一个列表,其中包含来自/bin应用程序文件夹的 .NET 程序集中的所有类及其依赖项。此列表中还包括任何其他 .NET 引用的程序集。IIS 执行此操作是为了确定其中哪些实现了 IHttpHandler 或 IHttpModule 接口,具体取决于您处理的是处理程序还是模块。为了检查来自应用/bin程序文件夹的所有程序集中的所有类,IIS 管理器控制台会在 inetmgr.exe 进程内创建一个子 .NET 应用程序域,这些类将被加载到该域中并检查是否实现了上述接口。

通常,.NET 程序集会编译为 Microsoft 中间语言 (MSIL),并且设计为平台中立(即它可以在 64 位和 32 位平台上运行)。您可以将 .NET 程序集编译为仅针对 32 位平台或仅针对 64 位平台。在这种情况下,MSIL 会进一步编译为特定于该平台处理器指令集的本机代码。当您执行此操作时,程序集无法加载到与编译的目标位数不匹配的进程中:尝试在 32 位进程内加载针对 64 位平台的程序集会返回错误。

由于 IIS 管理器控制台在 64 位 Windows 版本(默认情况下)的 64 位进程内运行,因此子 .NET 应用程序域将在 64 位进程内创建。当 IIS 管理器控制台尝试加载应用程序 /bin 文件夹中的某些 .NET 程序集以执行配置更改时,它无法知道这些程序集是否仅针对 32 位平台进行编译。如果遇到针对 32 位平台的程序集,则 inetmgr.exe 进程内的子 .NET 应用程序域中的程序集加载将停止,并且IIS 控制台中将显示“症状”部分中描述的错误。

此行为是设计使然,因为 IIS 管理器控制台无法确定应用程序的 .NET 程序集的目标位数。因此,它假定所有程序集都已编译为 MSIL 并且与平台无关,它们可以在 32 位和 64 位版本的 Windows 上运行。

解决方法

要解决此问题,请将 inetmgr.exe 进程的位数与必须在子 .NET 应用程序域内加载的目标程序集的位数进行匹配。要在 64 位版本的 Windows 上执行此操作,请从提升的命令提示符运行以下命令行:

mmc.exe /32 iis.msc

这将以 32 位模式加载 Microsoft 管理控制台 (MMC),并将 IIS 管理器控制台管理单元加载到 MMC。由于 IIS 控制台现在在 32 位进程中运行,因此 .NET 子应用程序域是在 32 位进程内创建的,这将与您尝试配置为托管处理程序或托管模块的程序集的目标位数相匹配。

重现步骤

创建一个实现IHttpModule或的类IHttpHandler,然后从 Visual Studio 编译类库项目以针对 32 位平台(项目构建设置中的平台目标:x86)。

获取生成的 .NET 程序集并将其部署到运行 IIS 的 64 位操作系统上的现有 Web 应用程序或网站的 bin 文件夹中。

进入 IIS 管理器并尝试通过界面添加托管处理程序或托管模块,您将收到错误。