我正在按照本指南构build一个带有静态链接的Qt独立应用程序。 除了最后一步之外,我还执行了其他步骤,其中包括将清单embedded到可执行文件中,并且应用程序可以在许多机器上正常运行。 但是,我发现其中一个可执行文件无法启动,因为MSVCP140.dll从计算机中丢失。 这是错误很可能是由于我没有包括清单的事实。 事实上,在上面的指南中明确写道:
你应该执行mt.exe来在应用程序中embedded一个清单,以避免错误,例如当应用程序在其他计算机上启动时丢失MSVCP90.dll
我的两个问题是:
如果您不想重新分配DLL,那么您需要将CRT静态链接到应用程序中。 如果你这样做了,你不会得到有关DLL丢失的错误。 你的应用程序不会使用DLL,因为它是静态链接的。
请注意,这与链接到Qt库是分开的 。 你可能连接那些静态的,但忘记了静态链接CRT。
如果你使用的是Visual Studio,你会在这里找到合适的旋钮:
项目→属性→配置→C / C ++→代码生成→运行库。
对于将要发布的发布版本,请确保将其设置为/MT
。 多线程是目前唯一可用的选项。 你不需要发布版本的“调试”版本,如果你是静态链接,你不需要DLL版本。 确保所有项目都设置为相同的选项, 以及链接的任何其他静态库。为避免兼容性问题,所有内容都需要使用相同版本的CRT。
如果您使用的是不同的IDE /编译器工具集,则需要查阅其文档以了解如何配置这些设置。 你没有提到问题中的具体问题。
至于清单,是的,所有的Windows应用程序都应该包含一个清单。 您的清单中究竟属于哪一个取决于您的应用程序在做什么以及您支持哪些Windows功能。 但有99%的机会表示支持常见控件的第6版。 你也会想把自己标记为UAC。 你正在编写一个不需要管理权限的标准应用程序的可能性是85%,所以你的清单将指定asInvoker
。 其他的东西也可以进入清单,如DPI意识,Windows版本支持等。MSDN文档包含更多的细节,特别是应用程序清单部分。
标准应用程序的示例清单可能如下所示:
<?xml version="1.0" encoding="UTF-8"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" manifestVersion="1.0"> <!-- Enable use of version 6 of the common controls (Win XP and later) --> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> <!-- Indicate UAC compliance, with no need for elevated privileges (Win Vista and later) --> <!-- (if you need enhanced privileges, set the level to "highestAvailable" or "requireAdministrator") --> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> <!-- Indicate high API awareness (Win Vista and later) --> <!-- (if you support per-monitor high DPI, set this to "True/PM") --> <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware> </windowsSettings> </application> <!-- Declare support for various versions of Windows --> <ms_compatibility:compatibility xmlns:ms_compatibility="urn:schemas-microsoft-com:compatibility.v1" xmlns="urn:schemas-microsoft-com:compatibility.v1"> <ms_compatibility:application> <!-- Windows Vista/server 2008 --> <ms_compatibility:supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" /> <!-- Windows 7/server 2008 R2 --> <ms_compatibility:supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" /> <!-- Windows 8/server 2012 --> <ms_compatibility:supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" /> <!-- Windows 8.1/server 2012 R2 --> <ms_compatibility:supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" /> <!-- Windows 10 --> <ms_compatibility:supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" /> </ms_compatibility:application> </ms_compatibility:compatibility> </assembly>
清单是一个简单的文本文件,遵循Microsoft定义的XML模式,使用SDK工具链接到应用程序的二进制文件。 具体来说, mt.exe
为你做这个,将清单合并到二进制文件中。 通常这是在链接时完成的。 微软的链接器会自动为你做。 我不确定其他厂商的连接器。 你当然可以调用mt.exe
来为你做一个后期制作步骤。 只要您安装了Windows SDK,它就会在您的计算机上。 示例命令:
mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1
如果你正在签署你的二进制文件,确保在嵌入清单后签名,因为这一步(显然)改变了二进制文件,从而使签名无效。