Qt开发windows程序中使用自定义manifest
最近在使用Qt开发一个PC工具,遇到了一些现象,开发好的exe文件在某些windows10系统上打开使用都是一切正常的,但关闭程序后会弹出以下窗口
程序兼容性助手,即PCA。那么这个弹窗触发究竟会是什么原因呢,在MSDN上有描述:
https://docs.microsoft.com/en-us/previous-versions/bb756937(v=msdn.10)?redirectedfrom=MSDN
我并没有从中分析到具体原因,但是明确一点就是有一种解决办法就是给exe增加manifest文件描述,以描述文件支持的系统版本,防止警告
那么Qt开发的程序如何添加manifest文件呢,网上很多博客描述的方法大致是两种:
- 一种是添加编译选项QMAKE_LFLAGS,但这种方法只适用于MSVC的编译器
- 另一种就是自己编写一个manifest.rc的文件,在文件内容中指定一个manifest路径,如下
CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "C:/Users/pc/Desktop/tools/tools/manifest.xml"
但第二种方法也有个坏处,就是需要在pro文件内添加RC_FILE=manifest.rc指定自定义的rc文件,这会导致在pro文件内的RC_ICONS变量QMAKE_TARGET_COMPANY变量等一系列的变量均失效,可以参考以下文档中的说明
https://doc.qt.io/qt-5/qmake-variable-reference.html
虽然这种rc文件全部都自定义的写法更加标准一些,但比起QMAKE里的写法显得有些丑陋。
那么这里给出一种直接在pro文件内添加manifest.xml的方法
QMAKE_MANIFEST = $$PWD/manifest.xml
不知道为啥在Qt5的最新文档里都没有这个选项,我一度以为pro不能支持这个,但事实上在qt的dev文档里有这个参数的描述
https://18.203.89.116/qt6-dev/qmake-variable-reference.html#qmake-manifest
而我使用的qt5.12.8这个版本中已经是可以支持这个选项了。
最后,就是解决PCA的问题了,解决办法很简单,就是在manifest.xml文件内增加支持的操作系统版本,那么在这个操作系统上将不会弹出PCA警告。这里示例写法如下:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity version="1.0.0.0" name="tools.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<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}" />
</application>
</compatibility>
</asmv1:assembly>