命令介面和 Shlwapi DLL 版本

本節說明如何判斷應用程式執行所在的殼層 DLL 版本,以及如何將應用程式設為特定版本的目標。

DLL 版本號碼

殼層檔中討論的一些程式設計項目,全都包含在兩個 DLL 中:Shell32.dll和Shlwapi.dll。 由於持續增強功能,這些 DLL 的不同版本會實作不同的功能。 在 Shell 參考檔中,每個程式設計專案都會指定最低支援的 DLL 版本號碼。 這個版本號碼表示程式設計專案是在該版本和後續版本的 DLL 中實作,除非另有指定。 如果未指定版本號碼,程式設計專案就會在所有現有的 DLL 版本中實作。

在 Windows XP 之前,新的 Shell32.dll 和 Shlwapi.dll 版本有時會隨附于新版本的 Windows Internet Explorer。 從 Windows XP 起,這些 DLL 不再提供為新版本 Windows 本身以外的可轉散發檔案。 下表概述不同的 DLL 版本,以及它們如何散發回 Microsoft Internet Explorer 3.0、Windows 95 和 Microsoft Windows NT 4.0。

Shell32.dll 4.0 版位於 Windows 95 和 Microsoft Windows NT 4.0 的原始版本中。 Shell 未使用 Internet Explorer 3.0 版本更新,因此Shell32.dll沒有 4.70 版。 Shell32.dll 4.71 和 4.72 版隨附于對應的 Internet Explorer 版本,但它們不一定安裝 (請參閱附注 1) 。 針對 Microsoft Internet Explorer 4.01 和 Windows 98 之後的版本,Shell32.dll和Shlwapi.dll分位的版本號碼。 一般而言,您應該假設 DLL 有不同的版本號碼,並個別測試每一個。

Shell32.dll

版本 散發平臺
4.0 Windows 95 和 Microsoft Windows NT 4.0
4.71 Microsoft Internet Explorer 4.0。 請參閱注意 1。
4.72 Internet Explorer 4.01 和 Windows 98。 請參閱注意 1。
5.0 Windows 2000 和 Windows Premium Edition (Windows Me) 。 請參閱附注 2。
6.0 Windows XP
6.0.1 Windows Vista
6.1 Windows 7

Shlwapi.dll

版本 散發平臺
4.0 Windows 95 和 Microsoft Windows NT 4.0
4.71 Internet Explorer 4.0。 請參閱注意 1。
4.72 Internet Explorer 4.01 和 Windows 98。 請參閱注意 1。
4.7 Internet Explorer 3.x
5.0 Microsoft Internet Explorer 5 和 Windows 98 SE。 請參閱附注 2。
5.5 Microsoft Internet Explorer 5.5 和 Windows Premium Edition (Windows Me)
6.0 Windows XP 和 Windows Vista

附注 1: Internet Explorer 4.0 或 4.01 的所有系統都有Shlwapi.dll (4.71 或 4.72 的相關版本,分別) 。 不過,對於 Windows 98 之前的系統,Internet Explorer 4.0 和 4.01 可以安裝或不使用所謂的 整合式殼層。 如果 Internet Explorer 與整合式殼層一起安裝,則也會安裝與 Shell32.dll (4.71 或 4.72) 相關聯的版本。 如果 Internet Explorer 未安裝整合殼層,Shell32.dll維持為 4.0 版。 換句話說,系統上有 4.71 或 4.72 版的Shlwapi.dll不保證Shell32.dll具有相同的版本號碼。 所有 Windows 98 系統都有 4.72 版的 Shell32.dll。

附注 2: 5.0 版Shlwapi.dll是以 Internet Explorer 5 散發,且可在安裝 Internet Explorer 5 的所有系統上找到,但 Windows 2000 除外。 版本 5.0 Shell32.dll是以原生方式與 Windows 2000 和 Windows (Windows Me) 版一起散發,以及 5.0 版的 Shlwapi.dll。

使用 DllGetVersion 來判斷版本號碼

從 4.71 版開始,Shell DLL 等會開始匯出 DllGetVersion。 應用程式可以呼叫此函式,以判斷系統上存在的 DLL 版本。

注意

DLL 不一定匯出 DllGetVersion。 嘗試使用它之前,請一律先測試它。

對於 Windows 2000 之前的 Windows 版本, DllGetVersion 會傳回 DLLVERSIONINFO 結構,其中包含主要和次要版本號碼、組建編號和平臺識別碼。 對於 Windows 2000 和更新版本系統, DllGetVersion 可能會改為傳回 DLLVERSIONINFO2 結構。 除了透過 DLLVERSIONINFO提供的資訊之外, DLLVERSIONINFO2也提供 Hotfix 編號來識別最新安裝的 Service Pack,以提供更健全的方式來比較版本號碼。 因為 DLLVERSIONINFO2 的第一個成員是 DLLVERSIONINFO 結構,所以後續的結構與回溯相容。

使用 DllGetVersion

下列範例函式 GetVersion 會載入指定的 DLL,並嘗試呼叫其 DllGetVersion 函式。 如果成功,它會使用宏,將 DLLVERSIONINFO 結構的主要和次要版本號碼封裝到傳回給呼叫應用程式的 DWORD 。 如果 DLL 未匯出 DllGetVersion,函式會傳回零。 使用 Windows 2000 和更新版本系統時,您可以修改 函式來處理 DllGetVersion 傳回 DLLVERSIONINFO2 結構的可能性。 如果是,請使用 該 DLLVERSIONINFO2 結構 ullVersion 成員中的資訊來比較版本、組建編號和 Service Pack 版本。 MAKEDLLVERULL宏可簡化將這些值與ullVersion中的值比較的工作。

注意

不正確使用 LoadLibrary可能會造成安全性風險。 如需如何使用不同 Windows 版本正確載入 DLL 的資訊,請參閱 LoadLibrary 檔。

#include "stdafx.h"
#include "windows.h"
#include "windef.h"
#include "winbase.h"
#include "shlwapi.h"

#define PACKVERSION(major,minor) MAKELONG(minor,major)

DWORD GetVersion(LPCTSTR lpszDllName)
{
    HINSTANCE hinstDll;
    DWORD dwVersion = 0;

    /* For security purposes, LoadLibrary should be provided with a fully qualified 
       path to the DLL. The lpszDllName variable should be tested to ensure that it 
       is a fully qualified path before it is used. */
    hinstDll = LoadLibrary(lpszDllName);
    
    if(hinstDll)
    {
        DLLGETVERSIONPROC pDllGetVersion;
        pDllGetVersion = (DLLGETVERSIONPROC)GetProcAddress(hinstDll, "DllGetVersion");

        /* Because some DLLs might not implement this function, you must test for 
           it explicitly. Depending on the particular DLL, the lack of a DllGetVersion 
           function can be a useful indicator of the version. */

        if(pDllGetVersion)
        {
            DLLVERSIONINFO dvi;
            HRESULT hr;

            ZeroMemory(&dvi, sizeof(dvi));
            dvi.info1.cbSize = sizeof(dvi);

            hr = (*pDllGetVersion)(&dvi);

            if(SUCCEEDED(hr))
            {
               dwVersion = PACKVERSION(dvi.info1.dwMajorVersion, dvi.info1.dwMinorVersion);
            }
        }
        FreeLibrary(hinstDll);
    }
    return dwVersion;
}

下列程式碼範例說明如何使用 GetVersion 來測試Shell32.dll為 6.0 版或更新版本。

LPCTSTR lpszDllName = L"C:\\Windows\\System32\\Shell32.dll";
DWORD dwVer = GetVersion(lpszDllName);
DWORD dwTarget = PACKVERSION(6,0);

if(dwVer >= dwTarget)
{
    // This version of Shell32.dll is version 6.0 or later.
}
else
{
    // Proceed knowing that version 6.0 or later additions are not available.
    // Use an alternate approach for older the DLL version.
}

專案版本

為了確保您的應用程式與.dll檔案的不同目標版本相容,版本宏會出現在標頭檔中。 這些宏是用來定義、排除或重新定義不同 DLL 版本的特定定義。 如需這些宏的深入描述,請參閱 使用 Windows 標頭

例如,宏名稱 _WIN32_IE 通常會在較舊的標頭中找到。 您必須負責將巨集定義為十六進位數位。 此版本號碼會定義使用 DLL 的應用程式目標版本。 下表顯示可用的版本號碼,以及每個版本對應用程式的影響。

版本 描述
0x0200 應用程式與 Shell32.dll 4.00 版和更新版本相容。 應用程式無法實作 4.00 版之後新增的功能。
0x0300 應用程式與 Shell32.dll 4.70 版和更新版本相容。 應用程式無法實作 4.70 版之後新增的功能。
0x0400 應用程式與 Shell32.dll 4.71 版和更新版本相容。 應用程式無法實作 4.71 版之後新增的功能。
0x0401 應用程式與 Shell32.dll 4.72 版和更新版本相容。 應用程式無法實作 4.72 版之後新增的功能。
0x0500 應用程式與 Shell32.dll 和 Shlwapi.dll 5.0 版和更新版本相容。 應用程式無法實作在 5.0 版Shell32.dll和Shlwapi.dll之後新增的功能。
0x0501 應用程式與 Shell32.dll 和 Shlwapi.dll 5.0 版和更新版本相容。 應用程式無法實作在 5.0 版Shell32.dll和Shlwapi.dll之後新增的功能。
0x0600 應用程式與 Shell32.dll 和 Shlwapi.dll 6.0 版和更新版本相容。 應用程式無法實作在 6.0 版之後新增Shell32.dll和Shlwapi.dll的功能。

如果您未在專案中定義 _WIN32_IE 宏,它會自動定義為0x0500。 若要定義不同的值,您可以將下列內容新增至 make 檔案中的編譯器指示詞;以所需的版本號碼取代0x0400。

/D _WIN32_IE=0x0400

另一種方法是在包含 Shell 標頭檔之前,在原始程式碼中新增類似下列的行。 以所需的版本號碼取代0x0400。

#define _WIN32_IE 0x0400
#include <commctrl.h>