从C程序中获取并报告Windows版本信息

3
我们有一个项目最初是为Win2K,然后是WinXP和Win7构建的,现在该项目已从使用VS2010的32位Win7程序转换为使用VS2017的64位Win10程序。 VS2017项目是从头开始创建的,然后导入和更新了旧源代码。
在创建新项目时,我将目标平台(在项目配置中的常规部分)设置为Windows 10,并且由于我没有特殊需求,所以设置了自动构建清单。
今天我注意到我们的对话框在程序中显示当前运行的Windows版本信息,指出我们正在运行Windows 8.1,内部版本号6.2。当我查找GetVersionInfo函数时,发现它会“欺骗”那些没有声明目标为Windows 10的程序。
我的问题分为两部分:
1. 因为我使用VS2017定位Windows 10并自动构建清单,为什么只对不针对Windows 10的程序撒谎的函数对我的程序说谎呢?如果要构建清单,它应该正确地构建清单,而不是误导信息吧?
2. 如果VS2017无法或不会正确地将我的程序定位为Windows 10,可以帮助我找到如何使用普通C项目手动执行此操作的示例吗? (Microsoft不会通过“只需向.rc文件添加必要的SXS符号”这样的评论提供帮助-我不会随机手动在.rc文件中添加代码,希望我无意中将其放在正确的位置!)
我坦承自己对清单的了解不足。到目前为止,我没有有意识地遇到过需要知道它的情况。
[编辑]对于“这是重复”的人只有一个微小的评论。我的程序不关心找到的Windows版本,但是需要尽可能详细地报告该版本的信息。我们在其中一个对话框中显示信息(并将其写入文件),我们在支持客户时使用该信息。这使我们能够确保我们使用与客户完全相同的Windows构建测试系统。 “重复”的主要焦点是确保程序在正确的Windows版本上运行,而我的程序正在报告我可以找到的所有Windows版本信息,所以对我来说,这实际上并不重复,尽管RtlGetVersion()函数(感谢@RemyLebeau)似乎解决了两种类型的问题。

1
你可能会对这个感兴趣。 - Jabberwocky
1
这已经有文献记录,并且在Stack Overflow上有数十甚至数百篇帖子讨论此问题。现在是时候进行一些研究了。 - David Heffernan
1
Visual Studio不会自动向应用程序清单中添加<compatibility>元素,因此您必须手动添加一个包含<compatibility>元素的清单片段,如@Jabberwocky发布的链接所述。 - zett42
2
如果您完全停止使用GetVersionEx()并改用不会对未启动的应用程序提供错误信息的其他API,例如RtlGetVersion(),或者像MSDN建议的系统DLL的GetFileVersionInfo(),则所有这些都无关紧要了。 - Remy Lebeau
1
@SteveValliere,你不需要DDK来使用RtlGetVersion()。你可以从MSDN中复制声明并将其粘贴到自己的代码中,然后使用GetProcAddress()在运行时访问该函数。链接的重复内容中有一个示例。 - Remy Lebeau
显示剩余4条评论
1个回答

1
请按照以下步骤进行操作:
首先,在您的项目文件夹中创建一个清单文件,例如命名为manifest.xml,然后将其添加到解决方案资源管理器中。

enter image description here

它应该具有以下内容:
<?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>
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"></supportedOS>
      <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"></supportedOS>
      <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"></supportedOS>
      <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"></supportedOS>
      <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"></supportedOS>
    </application>
  </compatibility>
</assembly>

然后在解决方案资源管理器中右键单击您的项目。并按如下所示进行修改:

enter image description here


实际上,您可以从清单中删除除XML头、<assembly>和<compatibility>元素(包括其内容)之外的所有内容。VS已经根据项目设置创建了其他部分,并将正确地与<compatibility>元素合并。 - zett42
所以,与让我困惑的微软声明相反,没有任何东西进入我的.rc文件!谢谢,我认为我可以从这里处理。 - Steve Valliere

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接