如何为Qt独立应用程序创建清单文件 [英] How to create manifest file for Qt standalone application

查看:106
本文介绍了如何为Qt独立应用程序创建清单文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在按照本指南构建具有静态链接的Qt独立应用程序.除最后一步外,我执行了每个步骤,最后一步是将清单嵌入到可执行文件中,并且应用程序可以在许多计算机上正常运行.但是,我发现其中一个无法启动可执行文件,因为计算机中缺少MSVCP140.dll.这很可能是由于我未包含清单所导致的错误.确实,上面的指南中清楚地写着:

I am building a Qt standalone application with static linking following this guide. I followed each step except the last one, which consists of embedding a manifest to the executable, and the application runs fine on a number of machines; I found one, however, where the executable cannot be launched because MSVCP140.dll is missing from the computer. This is error is most probably caused by the fact that I did not include the manifest. Indeed, in the guide above it is clearly written:

[...]您应该执行mt.exe来在应用程序中嵌入清单,以避免在其他计算机上启动该应用程序时出现诸如丢失MSVCP90.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没有安装在用于测试的计算机上.
  2. 如何为Qt应用程序生成此类文件?我按照指南的步骤操作,没有自动生成.manifest文件.因此,我假设在构建静态版本的Qt时我错过了一些东西,或者应该使用一些外部工具来执行此操作.例如,我看到了 Mage.exe 可以用来生成清单,但是我不知道这是否是正确的选择.
  1. What is the function of the manifest file in this case? Why is it that on some machines the application runs without it while for others it is necessary? From what I know, Visual Studio is installed on none of the computers that were used for the test.
  2. How do I generate such file for my Qt application? I followed the steps of the guide and no .manifest file is automatically generated. Hence, I am assuming that either I missed something when I built the static version of Qt or that I should use some external tool for doing it. For example, I saw that Mage.exe can be used to generate manifests, but I do not know if it's the right way to go in my case.

推荐答案

如果您不想重新分发DLL,则需要将CRT静态链接到应用程序.如果这样做,您将不会遇到有关DLL丢失的错误.您的应用不会使用DLL,因为它是静态链接的.

If you don't want to redistribute the DLLs, then you need to statically link the CRT into the application. If you had done that, you wouldn't be getting errors about DLLs missing. Your app wouldn't be using the DLLs because it is statically linked.

请注意,这与链接到Qt库是分开的.您可能是静态链接的,但忘记了静态链接CRT.

Note that this is separate from linking to the Qt libraries. You are probably linking those statically, but have forgotten to link the CRT statically.

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

If you're using Visual Studio, you'll find the appropriate knob here:
     Project → Properties → Configuration → C/C++ → Code Generation → Runtime Library.
For release builds, which you will be distributing, make sure it is set to /MT. Multithreaded is the only available option nowadays. You don't want a "debug" version for release builds, and you don't want the DLL version if you are statically linking. Make sure that all of your projects are set to the same option here, as well as any other static libraries that you link in. Everything needs to use the same version of the CRT in order to avoid compatibility problems.

如果您使用其他的IDE/编译器工具集,则需要查阅其文档以了解如何配置这些设置.您没有在问题中提及具体的人.

If you're using a different IDE/compiler toolset, you'll need to consult its documentation to learn how to configure these settings. You don't mention a specific one in the question.

对于清单,是的,所有Windows应用程序都应包含清单.清单中的确切内容取决于应用程序正在执行的操作以及所支持的Windows功能.但是,您有99%的机会要表示对通用控件版本6的支持.您还需要将自己标记为UAC意识.您正在编写不需要管理特权的标准应用程序的可能性为85%,因此清单中将指定asInvoker.清单中也可以包含其他内容,例如DPI意识,Windows版本支持等.应用程序清单.

As for the manifest, yes, all Windows applications should include a manifest. Exactly what belongs in your manifest depends on what your application is doing and what Windows features you support. But there is a 99% chance that you want to indicate support for version 6 of the common controls. You will also want to mark yourself as UAC aware. 85% likelihood that you are writing a standard app that does not need administrative privileges, so your manifest will specify asInvoker. Other things can go in the manifest, too, like DPI awareness, Windows version support, etc. The MSDN documentation contains more details, specifically the section on Application Manifests.

标准应用程序的清单清单可能看起来像这样:

A sample manifest for a standard application might look like this:

<?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 为您完成此操作,将清单合并到二进制的.通常,这是在链接时完成的. Microsoft的链接器将自动为您完成此操作.我不确定其他供应商提供的链接器.当然,您可以在构建后的步骤中调用mt.exe为您执行此操作.只要您安装了 Windows,它就会在您的计算机上. SDK .示例命令:

A manifest is a simple text file, following a Microsoft-defined XML schema, that you link into your application's binary using the SDK tools. Specifically, 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. Sample command:

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

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

If you are signing your binary, make sure that you sign after embedding the manifest, as this step (obviously) changes the binary, thus invalidating the signature.

这篇关于如何为Qt独立应用程序创建清单文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆