2012-01-15 16 views
3

RegNotifyChangeKeyValueを使用して64ビットレジストリキーの変更を監視しようとしています。 32ビットアプリケーションからこのキーを開くには、アクセスフラグKEY_WOW64_64KEYを追加する必要があります。RegNotifyChangeKeyValueを使用して64ビットキーの変更を監視する

残念ながら私はこのキーの変更を監視することができないようですが、それは32ビットのものだけです。

私は、レジストリ監視を実装するために使用しているユニットとともにデモプロジェクトを含めています。ダウンロードはこちらから:RegMonitor

手順問題を再現する:

  1. をプログラムをコンパイルします。それを管理者として実行します。 [スタート]ボタンをクリックします。

  2. regeditを開いて、そこに新しい値を追加します。Microsoft \ Windows \ CurrentVersion \ Runを

  3. \

    HKEY_LOCAL_MACHINE \ソフトウェアに移動します。 RegMonitorは変更を検出しません。

    HKEY_LOCAL_MACHINE \ SOFTWARE \ WOW6432NODE \ Microsoft \ Windows \ CurrentVersion \ Runを

  4. 移動はそこに新しい値を追加します。 RegMonitorはこの変更を検出します。

レジストリを開いたとき、私はKEY_WOW64_64KEYアクセスフラグを追加しましたが、それはまだキーのみWOW6432NODEリダイレクトを修正するための変更を通知されません。

RegNotifyChangeKeyValueを使用してそのようなキーを監視することは可能ですか?

+1

OK、私はここからサンプルアプリケーションをビルドしました:http://msdn.microsoft.com/en-us/library/windows/desktop/ms724892(v=vs.85).aspxそして、私は 'キーを開くときはKEY_WOW64_64KEYとなります。そして、コードはレジストリの64ビット部分の変更を私に通知しました。そうではなく、APIはエミュレータからの 'KEY_WOW64_64KEY'でうまく動作します。 –

+0

さて、あなたのアプリに 'Wow6432Node'をハードコードしました。それは常に悪い考えです。私はこれが純粋にこのアプリをテストするために行われたと信じています。 –

+0

デモ・アプリケーションはテスト目的のためのものです。そのため、私はその中にフラグをハードコードしています。 – smartins

答えて

2

以下の最小限の例は、レジストリの64ビットビューの変更を32ビットプロセスから検出します。私はあなたのプログラムについて何が違うのか分かりませんが、このコードは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で失敗しました。あなたのオブジェクトの1つは作成されませんでした。しかし、私はあなたがあなた自身のために並べ替えることができるかなり日常的なバグだと思う。


なぜ私はKEY_ALL_ACCESSを使用しているのだろうか。 RegNotifyChangeKeyValueに渡す鍵を開いたときにKEY_NOTIFYを使用しないでください。そして、キーで何が変更されたかのレポートを作成しようとすると、なぜKEY_READを使用しないのですか?今まで書こうとしていないので、KEY_ALL_ACCESSは適切ではありません。これらの変更を行うと、管理者として実行する必要はありません。

+0

David、これまでの回答とすべての調査に感謝します。 KEY_ALL_ACCESSの使用は、テストのためのものです。 デモプログラムも試しましたが、私のシステムでは、HKEY_LOCAL_MACHINE¥SOFTWARE¥Microsoft¥Windows¥CurrentVersion¥RunOnceの変更は、HKEY_LOCAL_MACHINE¥SOFTWARE¥Wow6432Node¥Microsoft¥Windows¥CurrentVersion¥RunOnceの場合にのみ通知されます。 あなたのシステムでは、そのレジストリキーの64ビットビューの変更が正しく検出されますか? – smartins

+0

はい、私のシステムでは、私のサンプルプログラムは64ビットビューの変更を検出します。私はUACで7 x64で勝利し、昇格していません。管理者として実行する必要はありません。 –

+0

私は何か不足しているかもしれませんが、このコードはKEY_WOW64_64KEYを使用していないようですので、確かにそれは32ビットビューだけを見ているのですか? –

関連する問題