0

私がこれについて間違っている場合は、どこかで読んだと確信しているので、訂正してください。Windowsサービスではレジストリの仮想化が無効になっています。また、x64バイナリでは仮想化が無効になっています。

HKEY_LOCAL_MACHINE \ SOFTWAREから値をロードする必要があるC#で記述されたWindowsサービスがあります。サービスをx86としてコンパイルして起動すると、値の読み取りに失敗します。x64と同じコードをコンパイルして起動すると、値が正しく読み取られます。サービスをx64マシンに加えてx86マシンでも実行できるようにしたいのですが、この値を読み取ることもできる必要があります。Windowsサービスに仮想化されていない値を読み取らせるにはどうすればよいですか?

4

1 に答える 1

1

レジストリの仮想化は、Windowsサービスでは無効になっています。また、x64バイナリでは仮想化が無効になっています。

はい、その通りです。64ビットプロセスと「サービスなどのインタラクティブではないプロセス」では無効になっています。

レジストリビューの詳細については、SOに関する以前の投稿をご覧ください。ビュー仮想化を混同しないでください。それらは異なります。32ビットアプリケーションを64ビットアプリケーションから分離するには、ビューが必要です。

C#では、OSに64ビットバージョンのレジストリを開くように要求するだけで同じことができます。

RegistryKey baseKey = RegistryKey.OpenBaseKey(
    RegistryHive.LocalMachine, RegistryView.Registry64);
RegistryKey key = baseKey.OpenSubKey("Software", false);
object value = key.GetValue("");

アプリケーション/サービスが32ビットマシンで実行される場合は、要求しても常に通常のレジストリを取得しますRegistryView.Registry64。64ビットマシンで実行している場合は、常に通常のバージョンのレジストリ(= 64ビットバージョン)を取得します。

副次的な質問:アプリケーションをX86またはX64としてコンパイルする必要があるのはなぜですか?AnyCPUを単純に保持することはできませんか?

仮想化には別の目的があり、レジストリを32ビットアプリケーションから分離することを目的としていませんが、レガシーアプリケーションとの互換性を高めるために、64ビットネイティブアプリケーションがレジストリを正しい方法で使用することを望んでいます。非仮想化バージョンのレジストリにアクセスするには、REG_KEY_DONT_VIRTUALIZEフラグを使用してレジストリキーを開く必要があります。このフラグをMicrosoft.Win32クラスで使用することはできないため、クラスDllImportとP/Invokeを使用する必要があります。

于 2012-05-23T13:58:43.197 に答える