Windows下如何让引用游戏引擎库的应用自动嵌入指定应用程序清单配置
实现方案
完全可以实现需求,以下是两种经过验证的落地方案,无需引用引擎的项目做任何手动配置:
方案1:通过MSBuild目标文件自动注入清单(官方推荐)
该方案完全符合微软推荐的清单配置逻辑,且所有配置收敛在引擎侧:
- 首先在引擎库项目根目录下创建三个文件:引擎专属清单文件
GameEngineDpiAware.manifest、MSBuild属性文件GameEngine.props、MSBuild目标文件GameEngine.targets - 清单文件配置DPI感知规则,示例内容如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <application xmlns="urn:schemas-microsoft-com:asm.v3"> <windowsSettings> <!-- 兼容Win7+的DPI感知声明 --> <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware> <!-- 兼容Win10 1703+的高版本DPI感知声明 --> <dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor, System</dpiAwareness> </windowsSettings> </application> </assembly>
- 编辑
GameEngine.targets文件,配置自动嵌入逻辑:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <ItemGroup> <!-- 自动将引擎自带清单嵌入到引用项目的最终可执行文件中 --> <EmbeddedManifest Include="$(MSBuildThisFileDirectory)GameEngineDpiAware.manifest" /> </ItemGroup> </Project>
- 在引擎库的项目配置文件(.vcxproj/.csproj)中添加导出规则,保证其他项目引用引擎时自动导入上述配置:
如果是SDK风格项目(.NET/C++ 新版项目),添加以下配置:
如果是传统C++项目,可在生成事件中将三个文件复制到输出目录,同时配置项目引用时自动导入targets即可。<ItemGroup> <None Include="GameEngine.props" Pack="true" PackagePath="build\" /> <None Include="GameEngine.targets" Pack="true" PackagePath="build\" /> <None Include="GameEngineDpiAware.manifest" Pack="true" PackagePath="build\" /> </ItemGroup>
方案2:API兜底兼容
可以和方案1同时使用做双重保险,避免极端场景下配置失效:
- 在引擎初始化入口(必须在第一个窗口创建前执行)调用DPI感知设置API,哪怕清单配置意外丢失也能生效:
C++示例代码:
#include <windows.h> #include <shellscalingapi.h> #pragma comment(lib, "Shcore.lib") void EngineInit() { // 优先适配最高版本DPI感知 if (!SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)) { // 降级适配旧版系统 SetProcessDpiAwareness(PROCESS_PER_MONITOR_DPI_AWARE); } // 其余引擎初始化逻辑 }
C#示例代码:
using System.Runtime.InteropServices; internal static class DpiInitializer { [DllImport("user32.dll", SetLastError = true)] private static extern bool SetProcessDpiAwarenessContext(IntPtr dpiContext); private static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4); public static void Run() { SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); } }
注意:该方式优先级低于清单配置,不会覆盖引用项目显式设置的清单规则,仅在没有对应清单配置时生效。
内容的提问来源于stack exchange,提问作者Alex Khazov
相关产品推荐
相关产品推荐

