Как создать файл манифеста для автономного приложения Qt

Я создаю автономное приложение Qt со статической связью, следуя этому руководству. Я следовал за каждым шагом, кроме последнего, который состоит из встраивания манифеста в исполняемый файл, и приложение отлично работает на нескольких машинах; Однако я обнаружил, что исполняемый файл не может быть запущен из-за отсутствия MSVCP140.dll на компьютере. Эта ошибка, скорее всего, вызвана тем, что я не включил манифест. Действительно, в руководстве выше четко написано:

[...] вам следует выполнить mt.exe, чтобы встроить манифест в приложение, чтобы избежать ошибок, таких как отсутствие MSVCP90.dll при запуске приложения на других компьютерах

Мои два вопроса:

  1. Какова функция файла манифеста в этом случае? Почему на некоторых машинах приложение запускается без него, а на других оно необходимо? Из того, что я знаю, Visual Studio не установлена ​​ни на одном из компьютеров, которые использовались для теста.
  2. Как мне сгенерировать такой файл для моего приложения Qt? Я следовал инструкциям руководства, и файл.manifest не создается автоматически. Следовательно, я предполагаю, что либо я что-то упустил, когда собирал статическую версию Qt, либо мне нужно использовать какой-то внешний инструмент для этого. Например, я видел, что Mage.exe можно использовать для создания манифестов, но я не знаю, правильно ли это делать в моем случае.

1 ответ

Решение

Если вы не хотите распространять библиотеки DLL, вам нужно статически связать ЭЛТ с приложением. Если бы вы сделали это, вы бы не получили ошибок об отсутствии DLL. Ваше приложение не будет использовать библиотеки DLL, потому что оно статически связано.

Обратите внимание, что это отдельно от ссылки на библиотеки Qt. Вы, вероятно, связываете их статически, но забыли связать ЭЛТ статически.

Если вы используете 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>

Манифест - это простой текстовый файл, соответствующий XML-схеме, определенной Microsoft, который вы связываете с двоичным файлом вашего приложения с помощью инструментов SDK. В частности, mt.exe делает это для вас, сливая манифест в двоичный файл. Часто это делается во время ссылки. Компоновщик Microsoft сделает это автоматически. Я не уверен насчет компоновщиков от других поставщиков. Можно конечно позвонить mt.exe сделать это для вас как шаг после сборки. Он будет на вашем компьютере, пока вы установили Windows SDK. Пример команды:

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

Если вы подписываете свой двоичный файл, убедитесь, что вы подписали его после встраивания манифеста, поскольку этот шаг (очевидно) изменяет двоичный файл, тем самым делая подпись недействительной.

Другие вопросы по тегам