如何在具有CMake构建的Windows DLL中嵌入特定的清单文件?

Ger*_*ald 10 windows manifest cmake

所以我有一个使用CMake构建的DLL,需要嵌入特定的清单文件.在Visual Studio设置中,我只需在清单工具/输入和输出/附加清单文件下添加清单文件名,它就可以正常工作.看起来这对CMake应该是可行的,但我一直无法弄清楚.

关于如何使用CMake完成此任务的任何想法?

Dav*_*ham 13

cmake-3.4现在已经学会了如何处理作为源文件列出的*.manifest文件.

https://cmake.org/cmake/help/v3.4/release/3.4.html#other


Cal*_*602 8

Additional Manifest Files在CMake中生成字段是不可能的(我检查了源代码).所以我们必须偷偷摸摸.

Visual生成自己的清单(yourapp.exe.manifest.intermediate)并将其与您的清单混合.因此,我们必须生成此清单一次,禁用生成,然后使用生成的清单.

生成清单:

如果您知道如何自己编写完整的清单,则此步骤是可选的.如果你像世界其他地方一样:

  • 像往常一样创建自己的清单
  • 在接口中添加它(Additional Manifest Files)
  • 重新编译,重新链接
  • 找到yourapp.exe.manifest(.exe旁边).将其复制到您的sources目录中并对其进行版本化.不要犹豫,重命名,如yourapp.final.manifest,如果它更清楚你

禁用代:

IF( WIN32 )
    SET ( CMAKE_SHARED_LINKER_FLAGS /MANIFEST:NO )
ENDIF( WIN32 )
Run Code Online (Sandbox Code Playgroud)

之后使用生成的清单:

这是通过手动调用mt.exe(清单工具,通常在链接器之后调用...除非它被禁用)在后构建步骤中完成的:

add_custom_command(
    TARGET YourApp
    POST_BUILD
    COMMAND "mt.exe" -manifest \"$(TargetDir)\\yourapp.final.manifest\" -outputresource:"$(TargetDir)$(TargetFileName)"\;\#1
    COMMENT "Adding manifest..." 
)
Run Code Online (Sandbox Code Playgroud)

(您可能需要将$(TargetDir)更改为$(OutDir),具体取决于您编写CMake的方式;使用Visual的Macros按钮查看其值.并记住:#1表示可执行文件,#2表示dll)


mya*_*lim 5

我刚刚发现,您可以使用mt.exe将多个清单文件(或可执行文件中嵌入的清单)合并到现有清单文件(或可执行文件)中。这样,您不必禁用Visual Studio的自动清单生成。您可以使用mt.exe作为后构建步骤添加新的清单数据。例:

program.exe嵌入了清单:

<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
</assembly>
Run Code Online (Sandbox Code Playgroud)

dpiaware.manifest包含:

<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings" xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</ms_windowsSettings:dpiAware>
    </windowsSettings>
  </application>
</assembly>
Run Code Online (Sandbox Code Playgroud)

运行命令:

mt.exe -manifest dpiaware.manifest "-inputresource:program.exe;#1" -outputresource:program.exe;#1
Run Code Online (Sandbox Code Playgroud)

现在program.exe包含嵌入式清单:

<?xml version="1.0"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <dependency>
    <dependentAssembly>
      <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="amd64" publicKeyToken="6595b64144ccf1df" language="*"/>
    </dependentAssembly>
  </dependency>
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel level="asInvoker" uiAccess="false"/>
      </requestedPrivileges>
    </security>
  </trustInfo>
  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <ms_windowsSettings:dpiAware xmlns:ms_windowsSettings="http://schemas.microsoft.com/SMI/2005/WindowsSettings" xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</ms_windowsSettings:dpiAware>
    </windowsSettings>
  </application>
</assembly>
Run Code Online (Sandbox Code Playgroud)