如何为 Qt 独立应用程序创建清单文件

How to create manifest file for Qt standalone application

我正在构建一个带有静态链接的 Qt 独立应用程序 this guide。我遵循了除最后一个步骤之外的每个步骤,最后一个步骤包括将清单嵌入到可执行文件中,并且该应用程序在许多机器上运行良好;但是,我发现了一个无法启动可执行文件的地方,因为计算机中缺少 MSVCP140.dll。这个错误很可能是由于我没有包含清单这一事实造成的。确实,在上面的指南中写得很清楚:

[...] you should execute mt.exe to embed a manifest inside the application to avoid error such as missing MSVCP90.dll when the application is started on other computers

我的两个问题是:

  1. 在这种情况下清单文件的作用是什么?为什么在某些机器上应用程序在没有它的情况下运行,而在其他机器上却有必要?据我所知,Visual Studio 安装在 none 台用于测试的计算机上。
  2. 如何为我的 Qt 应用程序生成这样的文件?我按照指南的步骤进行操作,但没有自动生成 .manifest 文件。因此,我假设我在构建 Qt 的静态版本时错过了一些东西,或者我应该使用一些外部工具来完成它。例如,我看到 Mage.exe 可用于生成清单,但我不知道这是否适合我的情况。

如果您不想重新分发 DLL,则需要将 CRT 静态 link 到应用程序中。如果你这样做了,你就不会收到关于 DLL 丢失的错误。您的应用不会使用 DLL,因为它是静态 linked.

请注意,这是从 link 到 Qt 库的 分开的 。您可能正在静态 link 那些,但忘记了 link CRT 静态。

如果您正在使用 Visual Studio,您会在这里找到合适的旋钮:
项目 → 属性 → 配置 → C/C++ → 代码生成 → 运行时库。
对于您将分发的发布版本,请确保将其设置为 /MT。多线程是当今唯一可用的选项。您不需要 "debug" 版本用于发布版本,如果您是静态 linking,则不需要 DLL 版本。确保所有 项目在此处设置为相同的选项,以及 您link 中的任何其他静态库. 一切都需要使用相同版本的CRT以避免兼容性问题

如果您使用不同的 IDE/compiler 工具集,则需要查阅其文档以了解如何配置这些设置。你在问题中没有提到具体的那个。

至于清单,是的,所有 Windows 应用程序都应包含清单。清单中具体包含哪些内容取决于您的应用程序正在做什么以及您支持哪些 Windows 功能。但是有 99% 的可能性您想要指示对公共控件版本 6 的支持。您还需要将自己标记为 UAC 感知。 85% 的可能性您正在编写不需要管理权限的标准应用程序,因此您的清单将指定 asInvoker。清单中也可以包含其他内容,例如 DPI 感知、Windows 版本支持等。MSDN documentation contains more details, specifically the section on Application Manifests.

标准应用程序的示例清单可能如下所示:

<?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 工具 link 将其添加到应用程序的二进制文件中。具体来说,mt.exe does this for you, merging the manifest into the binary. Often this is done at link time. Microsoft's linker will do it for you automatically. I'm not sure about linkers from other vendors. You can certainly call mt.exe to do it for you as a post-build step. It will be on your computer as long as you've installed the Windows SDK。示例命令:

mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1

如果您要签署二进制文件,请确保在嵌入清单后签署,因为此步骤(显然)会更改二进制文件,从而使签名无效。