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

5
我正在构建一个Qt的独立应用程序,使用静态链接遵循这个指南。我按照每个步骤操作,除了最后一步,该步骤包括将清单嵌入可执行文件中,应用程序在许多机器上运行良好;但是我发现,在某些机器上无法启动可执行文件,因为计算机缺少MSVCP140.dll。这个错误很可能是因为我没有包含清单造成的。事实上,在上述指南中明确写道:

[...] 您应该执行mt.exe将清单嵌入应用程序中,以避免出现错误,例如在其他计算机上启动应用程序时缺少MSVCP90.dll

我的两个问题是:

  1. 在这种情况下,清单文件的功能是什么?为什么有些机器可以在没有清单文件的情况下运行应用程序,而对于其他机器则必须要有清单文件?据我所知,进行测试的计算机中没有安装Visual Studio。
  2. 如何为我的Qt应用程序生成这样的文件?我按照指南的步骤操作,但没有自动生成.manifest文件。因此,我认为可能是我在构建Qt的静态版本时漏掉了某些步骤,或者需要使用一些外部工具来完成。例如,我看到Mage.exe可以用于生成清单文件,但我不知道在我的情况下是否正确。

1
为了避免缺少依赖项的错误,请将这些依赖项与您的应用程序一起打包。 - IInspectable
@IInspectable 我构建独立应用程序的原因是我希望能够仅发送可执行文件。由于依赖项不多,可执行文件仍然足够小,易于分发。 - lupod
1个回答

3
如果您不想重新分发DLL,则需要将CRT静态链接到应用程序中。如果您这么做了,您将不会收到关于缺少DLL的错误。因为您的应用程序是静态链接的,所以它将不使用DLL。
请注意,这与链接Qt库是分开的。您可能会静态链接那些库,但忘记了静态链接CRT。
如果您正在使用Visual Studio,则可以在此处找到相应的设置:
     Project → Properties → Configuration → C/C++ → Code Generation → Runtime Library。
对于您将要分发的发布版本,请确保将其设置为/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>

一个清单是一个简单的文本文件,遵循微软定义的XML架构,在应用程序中使用SDK工具链接到二进制文件中。特别地,mt.exe为您完成此操作,将清单合并到二进制文件中。通常在链接时进行此操作。微软的链接器会自动为您完成此操作。我不确定其他供应商的链接器是否会这样做。您可以作为构建后步骤调用mt.exe来完成这项任务。只要您安装了Windows SDK,它就会在计算机上。示例命令:
mt.exe -manifest MyApp.exe.manifest -outputresource:MyApp.exe;#1

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


Qt Creator怎么样? - Shaiful Islam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接