从dll函数调用正确获取Windows版本? [英] Get the Windows version correctly from a dll function call?
问题描述
假设我正在编写一个多功能的dll,其中包含用于获取OS版本的功能:
Suppose I'm writing a multi-purpose dll which includes a function for getting the OS version:
void get_os_version(DWORD *major, DWORD *minor)
{
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOsVersionInfoSize = sizeof(OSVERSIONINFOEX);
// deprecated but easier to use for this example's sake
GetVersionEx((OSVERSIONINFO*)&osvi);
*major = osvi.dwMajorVersion;
*minor = osvi.dwMinorVersion;
}
要正确检索高于Windows 8的Windows版本,需要嵌入清单以指定受支持的平台(请参阅详细信息
For the Windows version to be retrieved correctly for versions higher than Windows 8, it is required to embed a manifest that specifies the supported platforms (see details here).
因此,我在编译时使用/MANIFEST:NO
标志禁用了自动为dll文件生成清单的功能,而是添加了以下清单:
So I disable automatic generation of a manifest for my dll file using the /MANIFEST:NO
flag when compiling, and instead add the following manifest:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker" uiAccess="false"></requestedExecutionLevel>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
</application>
</compatibility>
</assembly>
,使用mt工具:
mt -manifest GetOsVersion.dll.manifest -outputresource:GetOsVersion.dll;#2
一切正常,没有错误.现在要使用dll,我创建一个简单的App.exe,该应用程序将加载dll并调用其函数:
All good and no errors. Now to use the dll, I create a simple App.exe which loads the dll and calls its function:
int _tmain(int argc, _TCHAR* argv[])
{
DWORD major, minor;
get_os_version(&major, &minor);
printf("%d.%d\n", major, minor);
return 0;
}
但是在Windows 10上运行App.exe时,令人惊讶的是,输出为:
But when running App.exe on Windows 10, surprise surprise, the output is:
6.2
,它是Windows 8的版本.如果我也将清单也应用到App.exe:
, which is the version for Windows 8. If I apply the manifest to the App.exe too:
mt -manifest GetOsVersion.dll.manifest -outputresource:App.exe;#1
,输出为预期的结果:
10.0
为什么会这样?我可以在不向可执行文件添加清单的情况下解决此问题吗?
Why is this happening? And can I solve this problem without adding a manifest to the executable?
我无法控制将使用我的库的应用程序,但是我仍然想正确地检索操作系统版本.
I don't have control over the applications that will use my library, but I still want to correctly retrieve the OS version.
推荐答案
MSDN页面上记录了用于确定实际操作系统版本的另一种方法:
An alternative method for determining the actual operating system version is documented on the MSDN page "Getting the System Version":
要获取操作系统的完整版本号,请在系统DLL之一(例如Kernel32.dll)上调用GetFileVersionInfo函数,然后调用VerQueryValue以获取文件版本信息的
\\StringFileInfo\\<lang><codepage>\\ProductVersion
子块.
无论应用程序是否具有清单,都可以通过DLL进行工作.
This will work from a DLL regardless of whether the application has a manifest.
(当然,GetVersionInfo和朋友没有返回实际的操作系统版本是有原因的:程序员有滥用这些信息的讨厌趋势.您应该认真考虑是否在DLL中提供这样的功能是真是个好主意.)
(Of course, there is a reason that GetVersionInfo and friends don't return the actual operating system version: programmers have a nasty tendency to misuse this information. You should seriously consider whether or not providing such a function in your DLL is really a good idea.)
这篇关于从dll函数调用正确获取Windows版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!