攻略:建立託管網頁核心應用程式

本教學示範如何建立使用 IIS 7 中 Hosted Web Core 功能的 Windows 主控台應用程式。

IIS 7 中的託管網頁核心功能允許您建立一個應用程式,載入 IIS 核心的實例,IIS 核心是 IIS 提供的基礎網頁應用程式及內容服務功能。 欲了解更多關於託管網頁核心的資訊,請參閱 託管網頁核心 API 參考資料。

你必須提供一個符合 ApplicationHost.config 檔案格式的應用程式設定檔。 不過,你不應該使用你的實際 ApplicationHost.config 檔案,因為裡面可能有與你網站設定衝突的設定。 欲了解更多如何為你的應用程式建立設定檔的資訊,請參閱 「攻略:為託管網路核心建立設定檔」。

本導覽中展示的任務包括以下幾項:

  • 為你的應用程式建立一個 C++ 專案。

  • 為你的應用程式加入 C++ 程式碼。

  • 編譯並測試你的應用程式。

  • 使用應用程式時遇到的錯誤與故障排除。

先決條件

完成範例步驟需要以下軟體:

  • IIS 7。

備註

雖然您必須在安裝 IIS 7 的電腦上執行 Hosted Web Core 應用程式,但不必在安裝 IIS 7 的電腦上編譯範例應用程式。 你可以在不同版本的 Windows 上編譯應用程式,然後複製到安裝了 IIS 7 的電腦。

  • Visual Studio 2005。

備註

你也可以使用 Visual Studio .NET 2003 或更早版本,雖然攻略步驟可能不完全相同。

建立託管網頁核心應用程式

在這部分的攻略中,你將為你的應用程式建立一個 C++ 控制台應用程式專案。

為你的應用程式建立 C++ 專案

  1. 啟動 Visual Studio 2005。

  2. 確認全球選項中,所有 SDK 的包含檔案路徑是否正確。

    1. 在 [工具] 功能表上,按一下 [選項] 。

      選項 對話框 會打開。

    2. 在樹狀檢視中展開專案 與解決方案 節點,然後點選 VC++ 目錄。

    3. 在 「Show 目錄」 的選項框中,選擇 「包含檔案」。

    4. 確認你安裝 SDK 包含檔案的路徑是否被列出。 如果路徑沒有列出,點選 新行 圖示,然後新增安裝 SDK 包含檔案的路徑。

    5. 按一下 確定。

  3. 建立一個新的 C++ 專案:

    1. 在 [檔案] 功能表上,指向 [開新檔案] ,然後按一下 [專案] 。

      新 專案 對話框會打開。

    2. 在 專案類型 窗格中,展開 Visual C++ 節點,然後點選 Win32。

    3. 在 範本 面板中,點選 Win32 專案。

    4. 在 名稱 框輸入 HostedWebTest。

    5. 在 地點 欄位輸入專案路徑。

    6. 按一下 確定。

      Win32 應用程式精靈會打開。

    7. 點選 應用程式設定。

    8. 在 應用程式類型中,點選 主控台應用程式。

    9. 按一下完成。

      Visual Studio 會開啟HostWebTest.cpp專案。

  4. 使用呼叫慣例設定專案以編譯__stdcall (/Gz):

    1. 在 專案 選單中,點選 HostedWebTest 屬性。

    2. 在樹狀檢視中展開 配置屬性 節點,展開 C/C++ 節點,然後點選 進階。

    3. 在 設定 框中,選擇 「所有設定」

    4. 在呼叫慣例框中,選擇 __stdcall(/Gz)。

    5. 按一下 確定。

新增應用程式的程式碼

本節說明如何將自動加入 C++ 檔案的程式碼替換成能執行 Hosted Web Core 的程式碼。

備註

這個範例會尋找 Inetsrv 資料夾中名為 HostedWebTest.config 的檔案。 你可以修改路徑和檔名,但必須提供有效的設定檔。 欲了解更多如何為你的應用程式建立設定檔的資訊,請參閱 「攻略:為託管網路核心建立設定檔」。

要為你的應用程式加入 C++ 程式碼

  1. 如果HostedWebTest.cpp檔案還沒開啟,請打開它,然後移除所有現有的 C++ 程式碼。

  2. 將以下 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;
    }
    
  3. 儲存HostedWebTest.cpp檔案。

編譯與測試應用程式

建立並儲存 C++ 檔案後,下一步是編譯並測試你的應用程式。

備註

如果你沒有在安裝了 IIS 7 的電腦上編譯應用程式,你必須先將 HostedWebTest.exe 檔案複製到安裝有 IIS 7 的電腦,才能測試該應用程式。

編譯並測試你的應用程式

  1. 編譯應用程式:

    1. 在 [建置] 功能表上,按一下 [建置解決方案]。

    2. 確認 Visual Studio 沒有回傳任何錯誤或警告。 如果你發現任何錯誤或警告,必須先解決這些問題,才能進行專案測試。

  2. 打開 Windows 檔案總管,找到你建立 C++ 專案時指定的資料夾。

    根據你的建置選項,你應該會在專案的預設資料夾裡看到一個名為 Debug 或 Release 的資料夾。

  3. 在 Debug 或 Release 資料夾中,找到名為 HostedWebTest.exe的檔案。

  4. 確認你的設定檔是否在你應用程式的正確資料夾裡。 舉例來說,這段攻略前面提到的程式碼範例,就是設計用一個名為 HostedWebTest.config 的檔案,該檔案位於你的 Inetsrv 資料夾裡。

  5. 打開命令提示字元視窗,將目錄切換到你 HostedWebTest.exe 檔案所在的路徑。

  6. 輸入 HostedWebTest 並按 ENTER 啟動應用程式。

  7. 你應該會看到應用程式的輸出,類似以下內容:

    DLL loaded successfully.
    WebCoreActivate successfully resolved.
    WebCoreShutdown successfully resolved.
    Activating the Web core...
    WebCoreActivate was successful.
    Press any key to continue...
    
  8. 不需按下鍵盤上的任何按鍵,即可最小化命令提示字元視窗。

  9. 根據你的設定設定,你可以打開網頁瀏覽器,瀏覽設定檔中定義的網站。

  10. 瀏覽完網站後,回到命令提示字元視窗並按空白鍵。

  11. 你應該會看到應用程式的輸出,類似以下內容:

    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 Map 拒絕」—此子狀態碼表示所請求資源的 MIME 類型未正確設定。 例如,如果你瀏覽一個副檔名為 .txt 的檔案,且你的設定檔中沒有將該副檔名加入 MIME 映射,就會遇到這段程式碼。

    • 404.4「無處理程序」—此子狀態碼表示尚未為所請求資源設定處理程序。 例如,如果你瀏覽一個副檔名 .htm 的檔案,且你沒有將靜態檔案處理器加入設定檔,就會遇到這段程式碼。

    • 404.7「檔案副檔名被拒絕」—此子狀態碼表示該檔名副檔名已被請求過濾阻擋。 例如,如果你瀏覽一個副檔名 .gif 的檔案,且請求過濾設定為拒絕存取該副檔名的檔案,你會遇到這段程式碼。

      這些錯誤都代表你應用程式設定檔的問題。 欲了解更多資訊,請參閱 攻略:建立 Hosted Web Core 的設定檔。

另請參閱