gpt4 book ai didi

winapi - 意外处理 DPI 感知

转载 作者:行者123 更新时间:2023-12-04 15:18:32 27 4
gpt4 key购买 nike

我有一项服务,可通过 CreateProcessAsUser 将可执行文件启动到用户 session 中,并在 STARTUPINFO 参数中指定桌面。它运行良好。

我的可执行文件没有显示出来,也没有调用任何与 DPI 相关的 API。

当我通过双击或通过 cmd.exe 手动启动我的可执行文件时,任务管理器正确地将 DPI 感知显示为“未感知”。

但是,当服务启动我的可执行文件时,任务管理器将 DPI 感知显示为“每个监视器”- 事实上,它的行为也是如此。

Setting the default DPI awareness for a process说:

There are two main methods to specify the default DPI awareness of a process:

  1. through an application manifest setting
  2. programmatically through an API call

这两件事我都没有做。

我确认 .exe 不是使用 mt.exe 显示的。我在以下设置函数断点:

  • user32.dll!SetProcessDpiAwarenessContext
  • user32.dll!SetThreadDpiAwarenessContext
  • shcore.dll!SetProcessDpiAwareness

没有断点;然而,当从该服务启动时,我只能在我已经进入 main 时附加我的调试器 - 并且似乎 DPI 感知已经在此时设置。

还有其他地方可以设置 DPI 感知吗?

这是一个混合 rust/C 应用程序 - 没有(例如).NET 依赖项被引用。


编辑:

使用 JIT 调试器,我可以在 mainCRTStartup 处中断并看到 DPI Awareness 在此时已经是“PerMonitor”。调用 SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_UNAWARE)SetProcessDpiAwareness(PROCESS_DPI_UNAWARE) 无效。


编辑:

当使用 CreateProcessAsUser 从我的服务启动时;可执行文件具有此环境变量:

__COMPAT_LAYER=HighDpiAware

传递给 CreateProcessAsUser 的环境是通过调用创建的:

CreateEnvironmentBlock 使用我的用户句柄。其余环境如预期。这是从哪里来的?当我在资源管理器中检查可执行文件的属性时,没有在可执行文件上设置兼容性选项...

最佳答案

我的服务以 SYSTEM 身份运行。当我调用 CreateProcessAsUser 时,在这种情况下,可执行文件也作为 SYSTEM 运行。我为 lpEnvironment 参数传递了 nullptrMSDN是这样说的:

A pointer to an environment block for the new process. If this parameter is NULL, the new process uses the environment of the calling process.

但是,当我检查我的可执行文件的环境时,我看到:

__COMPAT_LAYER=HighDpiAware

这是强制每个显示器的 DPI 意识。这很神秘,因为实际上 - 在 S-1-5-18 (SYSTEM) 的注册表中为该可执行文件设置了 AppCompatFlag,但我不知道这个值是如何或从哪里来的。

变量没有在我的服务上设置(它也作为 SYSTEM 运行)——大概服务没有获得 AppCompat 环境?但是,为什么我的子进程拥有它,尽管据说继承了它的父进程的环境?我想这些兼容性标志必须有特殊处理。

无论如何,我的问题的答案是:从 __COMPAT_LAYER 环境变量中删除 HighDpiAware

关于winapi - 意外处理 DPI 感知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63855309/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com