c++ - QueryDisplayConfig 不返回任何记录的值

标签 c++ windows winapi wdk

在系统启动时,我有一个 Windows 服务随其系统和用户进程一起加载。在加载用户进程后(作为管理员),我立即调用 QueryDisplayConfig 来检查显示特定信息。问题是有时,只是有时 QueryDisplayConfig 返回的值既不是其可能的返回值。

解决方法是在调用 QueryDisplayConfig 打开和关闭 Windows 注册表之前。这很有趣,但不知何故它解决了问题。我想知道 regedit.exe 强制 Windows 更新注册表的作用是什么。

这个问题可能没有解决办法,我只好求助于下面的解决方案,也是一种解决方案:

LONG lResult = QueryDisplayConfig(QDC_DATABASE_CURRENT, &PathArraySize, PathArray.data(), &ModeArraySize, ModeArray.data(), &CurrentTopology);
while (lResult != ERROR_SUCCESS &&
       lResult != ERROR_INVALID_PARAMETER &&
       lResult != ERROR_NOT_SUPPORTED &&
       lResult != ERROR_ACCESS_DENIED &&
       lResult != ERROR_GEN_FAILURE &&
       lResult != ERROR_INSUFFICIENT_BUFFER)
{
    Sleep(300);
    lResult = QueryDisplayConfig(QDC_DATABASE_CURRENT, &PathArraySize, PathArray.data(), &ModeArraySize, ModeArray.data(), &CurrentTopology);
}

我不想求助于这种丑陋的解决方法,而是让 Windows 以编程方式更新/刷新注册表。

最佳答案

通过 REGEDIT 搜索注册表时,如果我关闭/重新打开 REGEDIT 与不关闭/重新打开 REGEDIT 时,有时会得到不同的结果。这是在 WS08R2 上。我原以为这是 REGEDIT 本身的问题。现在听起来像是一个可能的 Windows 错误。如果是这种情况,就不会有任何漂亮的解决方法。

基于 Windows Internals注册表在内存中运行。所以对值/键的任何查询都将始终来自内存。如果值/键当前不在内存中,将首先读取它,但读取后的代码路径与它已经在内存中一样。磁盘上的配置单元不应比内存中配置单元的那部分更新。

因此,根据记录的设计,“刷新”注册表实际上没有任何意义。因此,我不希望有一个 API 来“刷新”。

我认为最不丑陋的方法(取决于您的审美)是尝试模仿 REGEDIT 的功能。当你关闭它时,它会保存它在注册表中上次浏览的位置,所以下次你运行 REGEDIT 时,它会(至少)打开并读取填充 REGEDIT 窗口所需的任何配置单元、键和值。

因此,您可以在下次从 QueryDisplayConfig 获得意外值时运行 REGEDIT 并查看正在显示的键和值。然后将其编码到您的程序中。当然,您实际上不必显示这些值,只需打开并阅读它们即可。

关于c++ - QueryDisplayConfig 不返回任何记录的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35096031/

相关文章:

C++ 模板 : Specialized member function to resolve case of ambiguous overload in primary template

windows - 当您按下 "Windows+D"时 Windows 将发送什么消息

delphi - 有没有办法通过Windows API获取VCL控件的名称?

c++ - 字符串的值不同,但打印它们显示相同的值

c++ - 如何在 OpenGL 中将像素绘制为多边形的纹理?

c++ - 以下结构是否为同一类型?

windows - Winsock Kernel的 "WskSendTo"函数在Win7 SP1上导致 "DRIVER_IRQL_NOT_LESS_OR_EQUAL"BSOD

不依赖 DLP 或质因数分解的 Java TLS

c++ - 如何判断一个进程 "virtual size"(WinXP)?

c++ - 帮助异步 I/O