如何在运行应用程序的系统上检查所需的 Windows API 功能是不是可用?

Posted

技术标签:

【中文标题】如何在运行应用程序的系统上检查所需的 Windows API 功能是不是可用?【英文标题】:How to check whether the needed Windows API function is available on the system where an application is running?如何在运行应用程序的系统上检查所需的 Windows API 功能是否可用? 【发布时间】:2019-05-24 14:47:44 【问题描述】:

我想使用一些特定于最新 Windows 10 版本的 Windows API 函数。例如。 CreatePseudoConsole() 支持 Windows Pseudo Console (ConPTY) 等功能仅在 Windows 10 版本 1809 中引入(Windows 10 秋季更新于 2018 年发布)。

经典方法是加载实现所需函数的 Windows 内核动态库(使用 LoadLibrary() 函数)并通过 GetProcAddress() 调用检查每个需要的函数。 Visual C++ 6.0 中引入的新方法称为Delay Loading

是否有任何现代(简单、清晰和透明)的方法来检查 Windows API 的哪些部分可用于正在运行的应用程序?或者它是一种检查应用程序正在运行的确切 Windows 10 版本的方法?我想使用像CreatePseudoConsole() 这样的函数,只有当它们可用时(如果它们不可用,应该执行一些其他代码)。

【问题讨论】:

MSDN 文档对此非常清楚。他们已经竭尽全力让您难以检查版本号。尝试获取 API。致电GetProcAddress。如果该功能可用,您将得到它。如果没有,NULL 将被返回。就是这样。 @DavidHeffernan 感谢您的评论! 不知何故,Visual C++ 6.0newer 在我的脑海中拒绝合作。 从概念上讲,我反对检查 API 可用性。您的应用程序要么需要它 - 并且您将最低版本声明为要求 - 要么它不需要它,并且您不必费心检查。否则,您最终会得到应用程序向用户提供不同功能的结果,而他们却不知道为什么它会以看似随机的方式运行。 安装程序应检查所需的 DLL 是否存在。 【参考方案1】:

GetProcAddress() 是满足您要求的唯一方法。绝对不要依赖于检测操作系统版本(在最近的 Windows 版本中,可靠地做到这一点变得越来越困难),而是依赖于所需的功能是否实际存在。

即使是链接器的delay-load feature 在内部使用GetProcAddress()。在这种情况下,您可以使用delay-load notification hook 来确定加载结果,以便相应地标记您的代码以供以后检查,甚至在需要时提供一个指向备用回退函数的指针。

这最后一部分很重要,因为延迟加载的函数在第一次调用之前是不会加载的,所以如果你调用了一个在运行时不存在的延迟加载函数,并且通知钩子不提供作为替代函数,您的代码可能会在尝试通过 NULL 指针执行函数时崩溃。为避免这种情况,您可以在调用函数之前显式调用 GetProcAddress()

【讨论】:

【参考方案2】:

如果 API 属于 API 集,it's recommended 使用 IsApiSetImplemented 而不是 GetProcAddress()

测试 Win32 API 是否可用的传统方法是使用 LoadLibrary 或 GetProcAddress。但是,由于 Windows 10 支持反向转发,因此这些方法并不是测试 API 集的可靠方法。

要确定特定 Win32 API 是否属于 API 集,请查看 API 参考文档中的要求表。

【讨论】:

以上是关于如何在运行应用程序的系统上检查所需的 Windows API 功能是不是可用?的主要内容,如果未能解决你的问题,请参考以下文章

如何检查是不是已应用 MPI 运行所需的所有先决条件?

如何检查鼠标点击位置是否在所需的应用程序上?

java中如何计算一个程序运行所需的最少时间,最多时间和平均时间?

为啥好多东西运行不了。出现“找不到所需的.dll文件?”

我们可以检查 Powershell 脚本所需的 Powershell/WPF/.Net 版本吗?

运行我的小程序所需的最低 Java 版本