【问题标题】:Build my application for a previous Windows platform为以前的 Windows 平台构建我的应用程序
【发布时间】:2017-05-24 23:02:51
【问题描述】:

背景

我正在使用VS2015WIN 7 上编写一个C++ 应用程序。此应用将在大于等于XP 的所有 Windows 操作系统上运行。

在我的代码中,我使用了很多 WINAPI 调用。

我希望在编译时防止使用未在 win XP 中定义的 API。

动机

在某些时候,我使用了函数 RegDeleteKeyEx function 却没有注意到这个 API 在 win XP 中不可用

解决方案

所以,我关注了这个帖子:Modifying WINVER and _WIN32_WINNT 并声明了这个:

#include <winsdkver.h>
#define _WIN32_WINNT        0x0501         
#define WINVER              0x0501 

在文件targetver.h

我希望在此修复之后,当我编译包含RegDeleteKeyEx function 用法的项目时,我会收到编译错误。 但我没有。

质量检查

我尝试寻找其他 new WINAPI in vista,并刚刚添加了对 GetTickCount64 function 的呼叫。编译时,我得到了这个:

error C3861: 'GetTickCount64': identifier not found

这证实了我的解决方案。

问题

我注意到对于RegDeleteKeyEx functionMinimum supported clientWindows Vista, Windows XP Professional x64 Edition

不过,我的应用也可以在 XP 32 中运行。

如何在这种用例中强制执行编译错误?

【问题讨论】:

  • 你运气不好。不幸的是,它在某些 SKU(XP x64、Win2003SP1)上可用。可以追溯到 Longhorn 的麻烦,当时的 SDK 添加是错误的。使用 #undef RegDeleteKeyEx 是获得编译错误的唯一半体面的解决方法。

标签: c++ windows winapi windows-xp


【解决方案1】:

不幸的是,正如我在“winreg.h”中看到的,RegDeleteKeyEx 没有条件编译(RegDeleteKey 除外)。所以在这种情况下没有(简单的)方法来触发编译错误。

唯一的选择(用于常规静态 DLL 加载)是在 winreg.h(或 windows.h)上创建您自己的包装器,该包装器将处理版本检查(例如在相应情况下为 #undef RegDeleteKeyEx)。


有时这种问题也可以使用动态 DLL 加载 (LoadLibrary / GetProcAdress) 来解决,您可以在其中检查特定功能在当前版本的 Windows 上是否存在,应用程序在其中运行(这样您就可以例如创建一个RegDeleteKey 包装器,它会在支持它的Windows 版本上调用RegDeleteKeyEx,如果在不支持它的版本下运行RegDeleteKey)。然后在运行时检查功能是否存在,因此程序可以在任何版本的系统上运行,并且仍然使用支持它们的版本上的最新功能(并且在较低的情况下没有 DLL“未解决的导入”加载问题不支持该功能的版本)。

【讨论】:

  • 动态负载最好使用Delay Loading处理,这样代码可以继续静态链接到RegDeleteKeyEx(),然后你可以使用dliFailGetProc失败钩子来替换机器上的替代函数缺少RegDeleteKeyEx() 的地方。这样,无论操作系统版本如何,代码都可以安全地调用RegDeleteKeyEx(),它会根据需要调用本机函数或自定义函数。
猜你喜欢
  • 1970-01-01
  • 2021-03-23
  • 2017-07-29
  • 1970-01-01
  • 1970-01-01
  • 2011-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多