损坏的 winapi 可执行清单
Posted
技术标签:
【中文标题】损坏的 winapi 可执行清单【英文标题】:Corrupted winapi executable manifest 【发布时间】:2016-09-21 12:32:42 【问题描述】:我正在开发一个使用 XML 文件的 Qt 应用程序。为了提高性能,我使用 pugixml 解析器而不是 Qt 的 dom 解析器。编译后,我的应用程序和所有依赖项(dll文件,帮助程序)被打包为一个winapi应用程序的资源,以创建单个exe文件。
在我需要将 QString::toStdString()
替换为 QString::toStdWString()
之前,一切正常。其原因是将名称中带有扩展字母 (ąęśćłóźżń
) 的文件读入 pugixml。我运行 pugixml::document::load_file()
之前通过 Qt 递归目录循环加载的数据。包含文件名的QString
s 转换为std::wstring
,然后转换为const wchar_t*
和qstring.toStdWString().c_str()
。
将string
s 替换为wstring
s 后,解压后的可执行文件运行良好。但是,打包后,最终的 .exe 文件有一个损坏的清单,如下所示:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="asInvoker"/>
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!--The ID below indicates application support for Windows Vista -->
<supportedOS Id="e2011457-1546-43c5-a5fe-008deee3d3f0"/>
<!--The ID below indicates below indicates application support for Windows
7 -->
<supportedOS Id="35138b9a-5d96-4fbd-8e2d-a2440225f93a"/>
<!--The ID below indicates application support for Windows 8 -->
<supportedOS Id="4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38"/>
<!--The ID below indicates application support for Windows 8.1 -->
<supportedOS Id="1f676c76-80e1-4239-95bb-83d0f6d0da78"/>
<!--The ID below indicates application support for Windows 10 -->
<supportedOS Id="8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a"/>
</application>
</compatibili
我使用的是 Windows 7 64 位,使用 MinGw -w64 shell 编译。最终包的 makefile 如下所示:
all: final.exe
final.exe: sad.o res.o
g++ -o final.exe -static-libgcc sad.o res.o resource.o -lcomctl32 -lshlwapi -mwindows
sad.o: sad.cpp
g++ -c sad.cpp
res.o: sad.rc resource.h resource.cpp
windres sad.rc res.o
g++ -c resource.cpp
clean:
rm -f *o final.exe
(res.o
包含windres打包的程序和所有依赖项,sad.cpp
包含从资源调用我的应用程序的winapi程序。
【问题讨论】:
什么是损坏的清单? 它包含在问题中。 XML 在所有节点关闭之前停止 然后我们需要查看生成清单资源的代码。 ...以及用于提取清单的代码(或工具)。 没有生成清单的代码。我猜 gcc 会生成一些默认清单。为了提取清单,我使用了带有 -m 选项的 sigcheck 程序 【参考方案1】:不确定是什么导致了问题,似乎是编译器错误,但是可以通过从包含有效清单的 xml 文件中创建 winapi 资源来解决此问题。我将描述该过程以供将来参考。
创建一个新的 manifest.rc 文件,如下所示:
#include <windows.h>
RT_MANIFEST BINARY MOVEABLE PURE "manifest.xml"
然后创建一个包含有效清单 XML 文件的 manifest.xml 文件并添加到 Makefile:
manifest.o: manifest.rc
windres manifest.rc manifest.o
不要忘记将 manifest.o 添加到 Makefile 中的主程序配方:
final.exe: sad.o res.o manifest.o
g++ -o final.exe -static-libgcc sad.o res.o resource.o manifest.o -lcomctl32 -lshlwapi -mwindows
【讨论】:
以上是关于损坏的 winapi 可执行清单的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot 可执行 jar “无效或损坏的 jar 文件”
如何创建清单文件以将我的可执行文件/插件指向我的特定版本的 Qt.dll?
IntelliJ Spring Boot:如何创建可执行的 jar