x64 Windows でのレジストリの扱い

嵌ったのでメモ.

64bit OS が出現した事でレジストリの扱いが少し変化していたようです.例えば,以下のコードで得られる結果は,ビルド時の設定,実行環境によって異なってきます.

Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE");
if (key == null) System.Console.WriteLine("failed to open subkey");
else {
    System.Console.WriteLine("subkey count: {0}", key.SubKeyCount);
    // HKEY_LOCAL_MACHINE\Software 以下のキーを列挙する・・・はず!
    foreach (System.String value in key.GetSubKeyNames()) {
        System.Console.WriteLine(value);
    }
}

どう異なるかについては,Issue reading x64 Registry keys で簡潔にまとめられていました.整理すると,Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE") で得られる実際のレジストリ・キーは以下のような規則になります.

  • Visual Studio において "x86" 設定でビルド
    • 実行環境が 32bit: HKEY_LOCAL_MACHINE\Software
    • 実行環境が 64bit: HKEY_LOCAL_MACHINE\Software\Wow6432Node
  • Visual Studio において "x64" 設定でビルド
    • 実行環境が 32bit: 実行できない
    • 実行環境が 64bit: HKEY_LOCAL_MACHINE\Software
  • Visual Studio において "Any CPU" 設定でビルド
    • 実行環境が 32bit: HKEY_LOCAL_MACHINE\Software
    • 実行環境が 64bit: HKEY_LOCAL_MACHINE\Software

今回は,x86 設定でビルドしていたため,HKLM\Software 以下を参照するつもりが HKLM\Software\Wow6432Node を参照したせいで嵌ってしまいました.レジストリを参照する際は,この辺りも注意しておく必要があるようです.