从dll函数调用正确获取Windows版本? [英] Get the Windows version correctly from a dll function call?

查看:105
本文介绍了从dll函数调用正确获取Windows版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我正在编写一个多功能的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆