C++ 运行时库设置为 /MT,但仍然缺少 api-ms-win*.dll

Posted

技术标签:

【中文标题】C++ 运行时库设置为 /MT,但仍然缺少 api-ms-win*.dll【英文标题】:C++ Run-Time Library is set to /MT, but api-ms-win*.dll's are still missing 【发布时间】:2015-05-25 15:38:44 【问题描述】:

我正在使用 Visual Studio 2013 (v120_xp),并且正在使用静态库进行编程。 “运行时库”设置为 /MT(多线程),所以我不需要外部 .dll。今天我添加了一个显示Windows 8 toast notifications from desktop app.的功能,一切正常,但是当我在Windows XP或Vista的虚拟机上测试程序时,它显示“api-ms-win-core-winrt-string-l1-1 -0.dll”和“api-ms-win-core-winrt-l1-1-0.dll”未找到。当我将提到的 *.dll 粘贴到与 .exe 相同的文件夹时 - 一切运行正常。我的问题是:我应该怎么做,将这些 .dll 链接为静态?我讨厌使用额外的 .dll,我希望我的程序非常便携(仅限于 1 个 .exe 文件)。对不起,如果我的问题不够清楚,但我希望它是可以理解的。我把编程当作一种爱好,所以我还有很多东西要学。

【问题讨论】:

【参考方案1】:

您调用的函数在 Windows 8 之前的版本中不可用。复制 DLL 肯定是错误的。您绝对不能合法地分发 Windows DLL,并且在任何情况下您都不能期望在不同版本上使用为一个版本设计的 DLL。

您将需要使用动态运行时链接到这些 DLL,并且仅在支持此功能的 Windows 版本上调用这些函数。

通过使用/delayload 或通过显式调用LoadLibraryGetProcAddress 来动态链接。

【讨论】:

非常感谢!效果很好!当然,我使用了一些诸如“IsWinEightOrLater()”之类的布尔值来防止在较旧的 Windows 版本上调用这些函数。关于那些 DLL——我已经粘贴了“6.2.9200.16384”版本,它在 XP/Vista 上运行良好——但你是对的,Windows 8.1 的“6.3.xxx”版本立即崩溃了。所以我完全同意这不是一个好的选择。再次感谢您的帮助! 永远不要复制系统 DLL。即使它看起来有效,但它总是错的。 使用操作系统版本检查(顺便说一句,微软有自己的IsWindows8Point1OrGreater()辅助函数)来决定是否调用给定函数不是最好的选择(并且在Win8中GetVersionEx()的破损.1,更容易出错)。 BEST 选项是完全不依赖操作系统版本号。使用GetProcAddress() 测试所需的函数是否实际存在,然后再调用它。这将始终给出正确的结果,并允许在较旧的操作系统版本中安装存根。 雷米说得很好。如果您使用 GetProcAddress,请让它指导您。如果您使用延迟加载,则需要进行版本检查。但是,只要您的应用程序正确显示,IsWindows8Point1OrGreater() 之类的功能就可以了。 感谢您提供更多提示!我正在使用一些主要/次要版本检查(现在更新到微软的版本助手)。我将测试“GetProcAddress()”,唯一的问题是我不知道函数使用什么 DLL,但我会更深入地研究它。

以上是关于C++ 运行时库设置为 /MT,但仍然缺少 api-ms-win*.dll的主要内容,如果未能解决你的问题,请参考以下文章

错误 MSB8024:不支持使用静态版本的 C++ 运行时库

VC运行时库(/MD/MT等)

VC 运行时库 /MD/MDd 和 /MT/MTd

一文带你弄懂Visual Studio:运行时库及MT/MTDMD/MDD

运行时库以及静态库,动态库之间的关系

链接脚本在编程中的高级运用之二——运行时库和C++特性支持