Shell 和 Shlwapi DLL 版本
本部分介绍如何确定应用程序正在运行的 Shell DLL 版本以及如何针对特定版本定位应用程序。
DLL 版本号
Shell 文档中讨论的一些编程元素都包含在两个 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 之前的系统,可以使用或不使用所谓的 集成 Shell来安装 Internet Explorer 4.0 和 4.01。 如果使用集成的 Shell 安装了 Internet Explorer,则还安装了 Shell32.dll(4.71 或 4.72)的相关版本。 如果在未安装集成 Shell 的情况下安装 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 除外。 Shell32.dll 版本 5.0 以本机方式与 Windows 2000 和 Windows 千年版(Windows Me)一起分发,以及 5.0 版 Shlwapi.dll。
使用 DllGetVersion 确定版本号
从版本 4.71 开始,Shell DLL 等开始导出 DllGetVersion。 应用程序可以调用此函数来确定系统上存在的 DLL 版本。
注意
DLL 不一定导出 DllGetVersion。 在尝试使用它之前,请始终对其进行测试。
对于早于 Windows 2000 的 Windows 版本,DllGetVersion 返回 DLLVERSIONINFO 结构,该结构包含主要版本号和次要版本号、内部版本号和平台 ID。 对于 Windows 2000 及更高版本系统,DllGetVersion 可能会返回 DLLVERSIONINFO2 结构。 除了通过 DLLVERSIONINFO提供的信息之外,DLLVERSIONINFO2还提供用于标识最新安装的 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>