演练:创建托管 Web Core 应用程序
本演练演示如何创建使用 IIS 7 中提供的托管 Web 核心功能的 Windows 控制台应用程序。
通过 IIS 7 中的托管 Web 核心功能,可以创建一个加载 IIS 核心实例的应用程序,这是 IIS 提供的基本 Web 应用程序和内容服务功能。 有关托管 Web 核心的详细信息,请参阅 托管 Web 核心 API 参考。
必须为应用程序提供遵循 ApplicationHost.config 文件格式的配置文件。 但是,不应使用实际ApplicationHost.config文件,因为它可能包含与网站设置冲突的设置。 有关如何为应用程序创建配置文件的详细信息,请参阅 演练:为托管 Web Core 创建配置文件。
本演练演示以下任务:
为应用程序创建 C++ 项目。
为应用程序添加 C++ 代码。
编译和测试应用程序。
排查使用应用程序时出现的错误。
先决条件
需要以下软件才能完成示例中的步骤:
- IIS 7。
注意
虽然必须在安装了 IIS 7 的计算机上运行托管 Web Core 应用程序,但不必在安装了 IIS 7 的计算机上编译示例应用程序。 可以在不同版本的 Windows 上编译应用程序,然后将应用程序复制到安装了 IIS 7 的计算机。
- Visual Studio 2005。
注意
也可以使用 Visual Studio .NET 2003 或更早版本,但演练步骤可能并不相同。
创建托管 Web Core 应用程序
在本演练的这一部分,你将为应用程序创建一个 C++ 控制台应用程序项目。
为应用程序创建 C++ 项目
启动 Visual Studio 2005。
验证全局选项是否具有 SDK 包含文件的所有正确路径:
在 “工具” 菜单上,单击 “选项” 。
“选项”对话框将打开。
在树视图中展开 “项目和解决方案 ”节点,然后单击“ VC++ 目录”。
在 “显示目录” 框中,选择“ 包括文件”。
验证是否已列出 SDK 的安装路径(包括文件)。 如果未列出路径,请单击“ 新建行 ”图标,然后添加安装 SDK 包含文件的路径。
单击 “确定” 。
创建新的 C++ 项目:
在 “文件” 菜单上,指向 “新建” ,然后单击 “项目” 。
“新建项目” 对话框随即打开。
在“ 项目类型 ”窗格中,展开 “Visual C++ ”节点,然后单击“ Win32”。
在 “模板 ”窗格中,单击“ Win32 项目”。
在“ 名称 ”框中,键入 “HostedWebTest”。
在“ 位置 ”框中,键入项目的路径。
单击 “确定” 。
Win32 应用程序向导随即打开。
单击“应用程序设置”。
在“ 应用程序类型”下,单击“ 控制台应用程序”。
单击“完成”。
Visual Studio 将打开 HostWebTest.cpp 项目。
使用
__stdcall (/Gz)
调用约定将项目配置为进行编译:在“ 项目 ”菜单上,单击“ HostedWebTest 属性”。
在树视图中展开 “配置属性” 节点,展开 C/C++ 节点,然后单击“ 高级”。
在 “配置 ”框中,选择“ 所有配置”
在“ 调用约定 ”框中,选择 __stdcall (/Gz) 。
单击 “确定” 。
为应用程序添加代码
本部分介绍如何将自动添加到 C++ 文件的代码替换为将运行托管 Web Core 的代码。
注意
本示例在 Inetsrv 文件夹中查找名为 HostedWebTest.config 的文件。 可以修改路径和文件名,但必须提供有效的配置文件。 有关如何为应用程序创建配置文件的详细信息,请参阅 演练:为托管 Web Core 创建配置文件。
为应用程序添加 C++ 代码
打开 HostedWebTest.cpp 文件(如果尚未打开),然后删除所有现有的 C++ 代码。
将以下 C++ 代码复制到 文件中:
#include "stdafx.h" #include <windows.h> #include <stdio.h> #include <conio.h> #include <hwebcore.h> // NOTE: Set the project's calling convention to "__stdcall (/Gz)". HRESULT _cdecl _tmain(int argc, _TCHAR* argv[]) { // Create a handle for the Web core DLL. HINSTANCE hDLL; // Specify the HRESULT for returning errors. HRESULT hr = S_OK; // Create arrays to hold paths. WCHAR wszInetPath[MAX_PATH]; WCHAR wszDllPath[MAX_PATH]; WCHAR wszCfgPath[MAX_PATH]; // Retrieve the path of the Inetsrv folder. DWORD nSize = ::ExpandEnvironmentStringsW( L"%windir%\\system32\\inetsrv",wszInetPath,MAX_PATH); // Exit if the path of the Inetsrv folder cannot be determined. if (nSize == 0) { // Retrieve the last error. hr = HRESULT_FROM_WIN32(GetLastError()); // Return an error status to the console. printf("Could not determine the path to the Inetsrv folder.\n"); printf("Error: 0x%x\n",hr); // Return an error from the application and exit. return hr; } // Append the Web core DLL name to the Inetsrv path. wcscpy_s(wszDllPath,MAX_PATH-1,wszInetPath); wcscat_s(wszDllPath,MAX_PATH-1,L"\\"); wcscat_s(wszDllPath,MAX_PATH-1,WEB_CORE_DLL_NAME); // Append the config file name to the Inetsrv path. wcscpy_s(wszCfgPath,MAX_PATH-1,wszInetPath); wcscat_s(wszCfgPath,MAX_PATH-1,L"\\HostedWebTest.config"); // Create a pointer to WebCoreActivate. PFN_WEB_CORE_ACTIVATE pfnWebCoreActivate = NULL; // Create a pointer to WebCoreShutdown. PFN_WEB_CORE_SHUTDOWN pfnWebCoreShutdown = NULL; // Load the Web core DLL. hDLL = ::LoadLibraryW(wszDllPath); // Test whether the Web core DLL was loaded successfully. if (hDLL == NULL) { // Retrieve the last error. hr = HRESULT_FROM_WIN32(GetLastError()); // Return an error status to the console. printf("Could not load DLL.\n"); printf("Error: 0x%x\n",hr); } else { // Return a success status to the console. printf("DLL loaded successfully.\n"); // Retrieve the address for "WebCoreActivate". pfnWebCoreActivate = (PFN_WEB_CORE_ACTIVATE)GetProcAddress( hDLL,"WebCoreActivate"); // Test for an error. if (pfnWebCoreActivate==NULL) { // Retrieve the last error. hr = HRESULT_FROM_WIN32(GetLastError()); // Return an error status to the console. printf("Could not resolve WebCoreActivate.\n"); printf("Error: 0x%x\n",hr); } else { // Return a success status to the console. printf("WebCoreActivate successfully resolved.\n"); // Retrieve the address for "WebCoreShutdown". pfnWebCoreShutdown = (PFN_WEB_CORE_SHUTDOWN)GetProcAddress( hDLL,"WebCoreShutdown"); // Test for an error. if (pfnWebCoreShutdown==NULL) { // Retrieve the last error. hr = HRESULT_FROM_WIN32(GetLastError()); // Return an error status to the console. printf("Could not resolve WebCoreShutdown.\n"); printf("Error: 0x%x\n",hr); } else { // Return a success status to the console. printf("WebCoreShutdown successfully resolved.\n"); // Return an activation status to the console. printf("Activating the Web core...\n"); // Activate the Web core. hr = pfnWebCoreActivate(wszCfgPath,L"",L"TestWebCore"); // Test for an error. if (FAILED(hr)) { // Return an error status to the console. printf("WebCoreActivate failed.\n"); printf("Error: 0x%x\n",hr); } else { // Return a success status to the console. printf("WebCoreActivate was successful.\n"); // Prompt the user to continue. printf("Press any key to continue...\n"); // Wait for a key press. int iKeyPress = _getch(); // Return a shutdown status to the console. printf("Shutting down the Web core...\n"); // Shut down the Web core. hr = pfnWebCoreShutdown(0L); // Test for an error. if (FAILED(hr)) { // Return an error status to the console. printf("WebCoreShutdown failed.\n"); printf("Error: 0x%x\n",hr); } else { // Return a success status to the console. printf("WebCoreShutdown was successful.\n"); } } } } // Release the DLL. FreeLibrary(hDLL); } // Return the application status. return hr; }
保存 HostedWebTest.cpp 文件。
编译和测试应用程序
创建并保存 C++ 文件后,下一步是编译和测试应用程序。
注意
如果未在安装了 IIS 7 的计算机上编译应用程序,则必须将HostedWebTest.exe文件复制到安装了 IIS 7 的计算机,然后才能测试该应用程序。
编译和测试应用程序
编译应用程序:
在“生成”菜单中,单击“生成解决方案”。
验证 Visual Studio 是否未返回任何错误或警告。 如果看到任何错误或警告,则必须在测试项目之前解决这些问题。
打开 Windows 资源管理器,找到创建 C++ 项目时指定的文件夹。
根据生成选项,应在项目的默认文件夹中看到名为 Debug 或 Release 的文件夹。
在 “调试” 或 “发布 ”文件夹中,找到名为 HostedWebTest.exe 的文件。
验证配置文件是否在应用程序的相应文件夹中。 例如,本演练前面列出的代码示例旨在使用位于 Inetsrv 文件夹中的名为 HostedWebTest.config 的文件。
打开命令提示符窗口,将目录更改为HostedWebTest.exe文件所在的路径。
键入 HostedWebTest 并按 Enter 启动应用程序。
应会看到来自应用程序的输出,如下所示:
DLL loaded successfully. WebCoreActivate successfully resolved. WebCoreShutdown successfully resolved. Activating the Web core... WebCoreActivate was successful. Press any key to continue...
最小化命令提示符窗口,而无需按键盘上的任何键。
根据配置设置,可以打开 Web 浏览器并浏览到配置文件中定义的网站。
浏览完网站后,返回到命令提示符窗口,然后按空格键。
应会看到来自应用程序的输出,如下所示:
Shutting down the Web core... WebCoreShutdown was successful.
排查错误
如果应用程序未加载,或在运行时返回错误,以下步骤将帮助你诊断可能遇到的一些错误。
排查应用程序中的错误
如果应用程序返回以下错误:
Could not load DLL. Error: 0x8007007e
这是ERROR_MOD_NOT_FOUND状态。 此错误指示无法找到Hwebcore.dll文件。 如果未安装 IIS,则会发生此错误。
如果应用程序返回以下错误:
DLL loaded successfully. WebCoreActivate successfully resolved. WebCoreShutdown successfully resolved. Activating the Web core... WebCoreActivate failed. Error: 0x8007000d
这是ERROR_INVALID_DATA状态。 此错误表示配置文件无法定位或包含错误。 你应该在 Windows 事件查看器中查找其他错误说明。
如果应用程序返回以下错误:
DLL loaded successfully. WebCoreActivate successfully resolved. WebCoreShutdown successfully resolved. Activating the Web core... WebCoreActivate failed. Error: 0x800700b7
这是ERROR_ALREADY_EXISTS状态。 此错误表示配置文件已加载,但它包含重复信息。 例如,你可能已定义多个应用程序池,或者可能创建了重复的网站绑定。 应检查 Windows 事件查看器以获取其他错误说明。
如果应用程序加载成功,但在浏览应用程序托管的网站时收到 HTTP 404 错误,则应检查应用程序创建的 IIS 日志,以获取 404 子状态代码。 下面是你可能会看到的一些子状态代码:
404.3“被 Mime 映射拒绝”- 此子状态代码指示未正确配置所请求资源的 MIME 类型。 例如,如果浏览到文件扩展名为 .txt 的文件,并且尚未将该扩展名添加到配置文件中的 MIME 映射,则会遇到此代码。
404.4“无处理程序”- 此子状态代码指示尚未为请求的资源配置处理程序。 例如,如果浏览到文件扩展名为 .htm 的文件,并且尚未将静态文件处理程序添加到配置文件,则会遇到此代码。
404.7“文件扩展名被拒绝”- 此子状态代码指示文件扩展名已被请求筛选阻止。 例如,如果浏览到文件扩展名为 .gif 的文件,并且请求筛选已配置为拒绝访问具有该扩展名的文件,则会遇到此代码。
其中每个错误都表示应用程序配置文件中的设置存在问题。 有关详细信息,请参阅 演练:为托管 Web 核心创建配置文件。