我尝试使用RegNotifyChangeKeyValue来监控64位注册表项的更改。 要从32位应用程序打开此密钥,我们必须添加访问标志KEY_WOW64_64KEY。
不幸的是,我似乎无法监控此密钥的更改,只有它的32位对应方。
我包括一个演示项目以及我用来实现注册表监控的单元。在此处下载:RegMonitor
重现问题的步骤:
编译程序。以管理员身份运行它。单击“开始”按钮。
打开注册表并导航到
HKEY_LOCAL_MACHINE \ SOFTWARE \微软\的Windows \ CurrentVersion \运行
在那里添加新值。 RegMonitor不会检测到任何变化。
导航至
HKEY_LOCAL_MACHINE \ SOFTWARE \ Wow6432Node \微软\的Windows \ CurrentVersion \运行
在那里添加新值。 RegMonitor将检测到此更改。
我在打开注册表时添加了KEY_WOW64_64KEY访问标志,但它仍然没有通知对正确密钥的任何更改,只有Wow6432Node重定向。
是否有可能使用RegNotifyChangeKeyValue来监控此类密钥?
答案 0 :(得分:2)
以下最小示例从32位进程检测注册表的64位视图中的更改。我不知道你的程序有什么不同,但是这段代码证明32位程序确实可以检测到两个视图中的变化。
我知道这并不能解决你的问题,但我希望它能引导你朝着正确的方向前进。
program RegMonitor;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
procedure Main;
const
dwFilter: DWORD =
REG_NOTIFY_CHANGE_NAME or
REG_NOTIFY_CHANGE_ATTRIBUTES or
REG_NOTIFY_CHANGE_LAST_SET or
REG_NOTIFY_CHANGE_SECURITY;
var
Error: Integer;
key: HKEY;
begin
Error := RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
'Software\Microsoft\Windows\CurrentVersion\RunOnce',
0,
KEY_NOTIFY or KEY_WOW64_64KEY,
key
);
if Error<>ERROR_SUCCESS then
RaiseLastOSError(Error);
try
Error := RegNotifyChangeKeyValue(
key,
True,
dwFilter,
0,
False
);
if Error<>ERROR_SUCCESS then
RaiseLastOSError(Error);
Writeln('Change detected');
Readln;
finally
RegCloseKey(key);
end;
end;
begin
Main;
end.
现在,至于你的程序,它看起来有很多问题。但是,基本问题,即意味着您未收到更改通知的问题,是您的事件创建错误。你这样创建:
CreateEvent(Nil, True, False, 'RegistryChangeMonitorEvent')
但你需要像这样创建它
CreateEvent(nil, False, True, nil)
我没有仔细研究这个事件的要求,文档没有提供任何线索。我所做的就是查找代码与MSDN example中的代码之间的差异。
对事件创建进行更改,您就可以开始接收通知了。但是,当我做了那个改变时,你的程序仍然没有工作,并且失败了AV。您的一个对象未创建。但是,我认为这些都是非常常见的错误,你可以自己解决。
我想知道你为什么要使用KEY_ALL_ACCESS
。当您打开要传递给KEY_NOTIFY
的密钥时,为什么不使用RegNotifyChangeKeyValue
?当您尝试构建关键字中已更改内容的报告时,为什么不使用KEY_READ
?由于您没有尝试永远写作,KEY_ALL_ACCESS
不合适。如果您进行了这些更改,则无需以管理员身份运行。