QueryDisplayConfig 没有 return 任何记录的值
QueryDisplayConfig does not return any of its documented values
系统启动时,我有一个 Windows 服务随其系统和用户进程一起加载。在加载用户进程后(作为管理员),我立即调用 QueryDisplayConfig 来检查显示特定信息。问题是有时,只是有时 QueryDisplayConfig returns 的值既不是其可能的 return 值。
解决方法是在调用 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 update/refresh 注册表。
通过 REGEDIT 搜索注册表时,如果我 close/reopen REGEDIT,我有时会得到不同的结果,如果我不这样做。这是在 WS08R2 上。我原以为这是 REGEDIT 本身的问题。现在听起来像是一个可能的 Windows 错误。如果是这种情况,就不会有任何漂亮的解决方法。
基于Windows Internals注册表在内存中运行。因此 values/keys 的任何查询都将始终来自内存。如果value/key当前不在内存中,则先读取,但读取后的代码路径与已经在内存中一样。磁盘上的配置单元不应该比内存中的那部分配置单元更新。
因此 "refreshing" 根据记录的设计,注册表实际上没有意义。因此我不希望有 API 到 "refresh"。
我认为最不丑陋的方法(取决于您的审美)是尝试模仿 REGEDIT 的功能。当你关闭它时,它会保存它在注册表中上次浏览的位置,所以下次你 运行 REGEDIT 时,它会(至少)打开并读取填充 REGEDIT 所需的任何配置单元、键和值 window。
因此,您可以 运行 下次从 QueryDisplayConfig
获得意外值时重新编辑并查看正在显示的键和值。然后将其编码到您的程序中。当然,您实际上不必显示这些值,只需打开并阅读它们即可。
系统启动时,我有一个 Windows 服务随其系统和用户进程一起加载。在加载用户进程后(作为管理员),我立即调用 QueryDisplayConfig 来检查显示特定信息。问题是有时,只是有时 QueryDisplayConfig returns 的值既不是其可能的 return 值。
解决方法是在调用 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 update/refresh 注册表。
通过 REGEDIT 搜索注册表时,如果我 close/reopen REGEDIT,我有时会得到不同的结果,如果我不这样做。这是在 WS08R2 上。我原以为这是 REGEDIT 本身的问题。现在听起来像是一个可能的 Windows 错误。如果是这种情况,就不会有任何漂亮的解决方法。
基于Windows Internals注册表在内存中运行。因此 values/keys 的任何查询都将始终来自内存。如果value/key当前不在内存中,则先读取,但读取后的代码路径与已经在内存中一样。磁盘上的配置单元不应该比内存中的那部分配置单元更新。
因此 "refreshing" 根据记录的设计,注册表实际上没有意义。因此我不希望有 API 到 "refresh"。
我认为最不丑陋的方法(取决于您的审美)是尝试模仿 REGEDIT 的功能。当你关闭它时,它会保存它在注册表中上次浏览的位置,所以下次你 运行 REGEDIT 时,它会(至少)打开并读取填充 REGEDIT 所需的任何配置单元、键和值 window。
因此,您可以 运行 下次从 QueryDisplayConfig
获得意外值时重新编辑并查看正在显示的键和值。然后将其编码到您的程序中。当然,您实际上不必显示这些值,只需打开并阅读它们即可。