Shell 和 Shlwapi DLL 版本
本節說明如何判斷應用程式執行所在的殼層 DLL 版本,以及如何以特定版本為目標的應用程式。
DLL 版本號碼
除了殼層檔案中討論的少數程式設計元素以外的所有專案都包含在兩個 DLL 中:Shell32.dll 和 Shlwapi.dll。 由於持續增強功能,這些 DLL 的不同版本會實作不同的功能。 在整個 Shell 參考檔中,每個程式設計專案都會指定最低支援的 DLL 版本號碼。 這個版本號碼表示除非另有指定,否則程式設計專案會實作在該版本和後續版本的 DLL 中。 如果未指定版本號碼,則程式設計專案會在所有現有的 DLL 版本中實作。
在 Windows XP 之前,有時會提供新版 Windows Internet Explorer 的新 Shell32.dll 和 Shlwapi.dll 版本。 從 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 Millennium 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 Millennium 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 Millennium Edition (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也提供可識別最新已安裝 Service Pack 的 Hotfix 編號,以提供更健全的方式來比較版本號碼。 因為 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>