2009-09-24 8 views
6

.NETモジュールで、Windows Registryにアクセスして、RegistryKeyクラスを使用して異常な動作が検出されました。.NETを使用してWindowsレジストリにアクセスしますか?

例えば、私は、レジストリにアクセスする.NETモジュール、testcom.dllを、書かれています。このtestcom.dllファイルは、ネイティブの32ビットアプリケーションと64ビットアプリケーションの両方で使用されます。私の要求は、regkeyの値を得ることです(パスはHKEY_LOCAL_MACHINE\SOFTWARE\Test\MyParametersで、キーの名前はAgeです)。この「Age」キーは、32ビットマシン上の32ビットレジストリと、64ビットマシン上の64ビットレジストリ(WOW64ではなく)になります。 64ビットマシン上で

32ビットアプリケーションがtestcom.dllを使用している場合、キー「年齢」がWOW64レジストリ内で検索されます。 64ビットアプリケーションがtestcom.dllを使用している場合、キー "Age"は64ビットレジストリで検索されます。

私の要件は、アプリケーションがtestcom.dllファイルを使用して何でも、64ビットマシン上で64ビットのレジストリのキーを読み取ることです。これどうやってするの?

+0

Thats odd。私はかつてレジストリのキーと値を調べるアプリケーションを書いたとき、私は64ビットOS上で動作しているときに32ビットアプリケーションキーのパスを手動で変更しなければならなかった。 おそらくコードを投稿できますか?あなたのキーを読み込む方法が私のものと違うかどうかを確認するには? –

+0

また、アプリケーションは32ビットアプリケーションでした。デフォルトではWOW64は検索されませんでした。 –

答えて

4

は、私は同様の問題があった、と私が見つけた最良の答えは、具体的KEY_WOW64_64KEYsamDesiredパラメータを論理和(OR)、背面(例えばRegOpenKeyExなど)のWin32レジストリ関数に落下し、適切なRegistry Key Security and Access Rightsに渡すことです。

それはひどかった、と私はあなたがここに良い答えを聞くことを願っています。

+0

あなたのお返事ありがとうございます。私はまた、最高のために願っています:) –

+0

最終的に動作するように見えるお返事ありがとうございます。 – rogerdpack

2

のWin32 APIに戻すに関するブレアの答えは、これを達成するための最善の方法についてです内のRegOpenKeyEx関数を呼び出します。

Windows自体は、Registry RedirectorRegistry Reflectionを使用して、特定のレジストリの場所を論理ビューにマップします。

あなたは、次のMSDNの記事でこのプロセスの詳細を読むことができます:
32-bit and 64-bit Application Data in the Registry

のWin32 APIにもかかわらず、これを達成するための最良の方法であること、これはの場所を「ハードコーディング」の可能性でありますレジストリを取得しようとしていますが、これは考えられる問題があります(Microsoft自身がこの方法をサポートしていません)。 あなたはこのスタックオーバーフローの質問にこの詳細を読むことができます:
How to open a WOW64 registry key from a 64-bit .NET application

最終的には、Win32 APIのは、現時点では(そうでない場合は、最もエレガントな)最善の解決策についてのようです。マイクロソフトから
ヒーススチュワートはthis MSDN Social質問に次のような答えが得られます。

は残念ながら Microsoft.Win32名前空間の下で管理さ レジストリAPIへのそれらのフラグを渡す する方法はありません。 あなたが言及したRegCreateKeyExとして などのネイティブAPIをP /呼び出しする必要があります。

の場合は、データを32ビットビューまたは64ビットビューの レジストリに格納することを検討してください。MSDNのトピックレジストリ リダイレクタを使用すると、おそらくに精通している がリダイレクトされるキーを、持っている、と話題レジストリ リフレクションは 値が32と 64ビットのキーの間にコピーされているキーがあります。

確かにあなたは、少なくともいくつかのレジストリデータを共有すること 両方のあなたの32ビットおよび64ビット・アプリケーションに を望む場合は はまたあなたのキーのレジストリ 反射を有効にすることを検討可能性がある、別のビューを必要とする場合。 詳細 の詳細については、 RegEnableReflectionKeyのドキュメントを参照してください。

2

次のコードでは、GetAge()がキー値を返します。キーが存在しない場合はnullを返します。

[DllImport("Advapi32.dll")] 
static extern uint RegOpenKeyEx(UIntPtr hKey, string lpSubKey, uint ulOptions, int samDesired, out int phkResult); 
[DllImport("Advapi32.dll")] 
static extern uint RegCloseKey(int hKey); 
[DllImport("advapi32.dll", EntryPoint = "RegQueryValueEx")] 
public static extern int RegQueryValueEx(int hKey, string lpValueName, int lpReserved, ref uint lpType, System.Text.StringBuilder lpData, ref uint lpcbData); 

public const int KEY_QUERY_VALUE = 0x0001; 
public const int KEY_WOW64_64KEY = 0x0100; 

static public string GetAge() 
{ 
    string EPG_REGKEY = @"SOFTWARE\Test\MyParameters"; 
    UIntPtr HKEY_LOCAL_MACHINE = (UIntPtr)0x80000002; 
    int hkey = 0; 

    try 
    { 
     uint lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, EPG_REGKEY, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, out hkey); 
     if (0 != lResult) return null; 
     uint lpType = 0; 
     uint lpcbData = 1024; 
     StringBuilder AgeBuffer = new StringBuilder(1024); 
     RegQueryValueEx(hkey, "Age", 0, ref lpType, AgeBuffer, ref lpcbData); 
     string Age = AgeBuffer.ToString(); 
     return Age; 
    } 
    finally 
    { 
     if (0 != hkey) RegCloseKey(hkey); 
    } 
} 
9

対象の.Netバージョンをv4に変更できる場合は、新しいOpenBaseKey関数を使用できます。

RegistryKey registryKey; 
if (Environment.Is64BitOperatingSystem == true) 
{ 
    registryKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); 
} 
else 
{ 
    registryKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry32); 
} 
関連する問題