0

この C# の例に従って、いくつかのレジストリ値をクエリできますが、すべてではありません。

タイプがわからない場合に、リモート マシンからレジストリ値を取得する方法を教えてください。(C#)

CurrentVersion、ProductName などのレジストリ キーを確実に取得できますが、CSDVersion を取得しようとすると失敗します。

.NET 2.0 と .NET 4.0 の両方でコンパイルしましたが、結果は同じです。ローカル マシンとリモート マシンにクエリを実行してみました。どちらも他のレジストリ値を返すことができますが、この特定の値は返せません。

どちらも x64 マシン (Windows 7 Ultimate および Windows 2008 R2) であるため、いずれの方法でもレジストリにアクセスする際に問題は発生しません。

私が見つけた奇妙なことの 1 つは、EnumValues 関数が返す値は 17 個だけで、この特定のレジストリ キーには 21 個あることです。欠落している 4 つのうち、CSDVersion はその 1 つです。

これらの 4 つの値が戻ってこない理由を誰かが知っているかどうか知りたいのですが、残りのすべての値は戻ってきますか? 欠損値:

  • CSD バージョン - Reg_sz
  • DigitalProductID - Reg_binary
  • DigitalProductId4 - Reg_binary
  • 製品 ID - Reg_sz

本当に奇妙なのは、.NET 2.0 で作成され、このようなことを行うクラス ライブラリを持つ別のプロジェクトがあることです。ライブラリの NUnit テストを実行すると、このクエリは正常に機能し、21 個の値すべてが返されます。しかし、このライブラリを別のプロジェクトで実行すると、機能しません。

ライブラリを呼び出すプロジェクトのコードをステップ実行しましたが、それを行うと、17 エントリしか返されません。そのため、何が起こっているのかを説明するのに途方に暮れています。

次にどこへ行こうか考えている人はいますか?以下は私が使用している正確なコードであり、上記の特定のケースでは機能しません

using System;
using System.Management;
using System.Management.Instrumentation;

namespace GetCSDVersion
{
    public enum RegHive : uint
    {
        HKEY_CLASSES_ROOT = 0x80000000,
        HKEY_CURRENT_USER = 0x80000001,
        HKEY_LOCAL_MACHINE = 0x80000002,
        HKEY_USERS = 0x80000003,
        HKEY_CURRENT_CONFIG = 0x80000005
    }

    public enum RegType
    {
        REG_SZ = 1,
        REG_EXPAND_SZ,
        REG_BINARY,
        REG_DWORD,
        REG_MULTI_SZ = 7
    }

    class Program
    {
        static void Main(string[] args)
        {
            const string strComputer = "localhost";

            ConnectionOptions options = new ConnectionOptions();
            options.Impersonation = ImpersonationLevel.Impersonate;
            options.EnablePrivileges = true;
            //options.Username = "";
            //options.Password = "";

            ManagementScope myScope = new ManagementScope("\\\\" + strComputer + "\\root\\default", options);
            ManagementPath mypath = new ManagementPath("StdRegProv");
            ManagementClass mc = new ManagementClass(myScope, mypath, null);

            object oValue = GetValue(mc, RegHive.HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", "CSDVersion");
            Console.WriteLine(oValue.ToString());
        }

        public static object GetValue(ManagementClass mc, RegHive hDefKey, string sSubKeyName, string sValueName)
        {
            RegType rType = GetValueType(mc, hDefKey, sSubKeyName, sValueName);

            ManagementBaseObject inParams = mc.GetMethodParameters("GetStringValue");
            inParams["hDefKey"] = hDefKey;
            inParams["sSubKeyName"] = sSubKeyName;
            inParams["sValueName"] = sValueName;

            object oValue = null;

            switch (rType)
            {
                case RegType.REG_SZ:
                    ManagementBaseObject outParams = mc.InvokeMethod("GetStringValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["sValue"];
                    }
                    else
                    {
                        // GetStringValue call failed
                    }
                    break;

                case RegType.REG_EXPAND_SZ:
                    outParams = mc.InvokeMethod("GetExpandedStringValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["sValue"];
                    }
                    else
                    {
                        // GetExpandedStringValue call failed
                    }
                    break;

                case RegType.REG_MULTI_SZ:
                    outParams = mc.InvokeMethod("GetMultiStringValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["sValue"];
                    }
                    else
                    {
                        // GetMultiStringValue call failed
                    }
                    break;

                case RegType.REG_DWORD:
                    outParams = mc.InvokeMethod("GetDWORDValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["uValue"];
                    }
                    else
                    {
                        // GetDWORDValue call failed
                    }
                    break;

                case RegType.REG_BINARY:
                    outParams = mc.InvokeMethod("GetBinaryValue", inParams, null);

                    if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
                    {
                        oValue = outParams["uValue"] as byte[];
                    }
                    else
                    {
                        // GetBinaryValue call failed
                    }
                    break;
            }

            return oValue;
        }

        public static RegType GetValueType(ManagementClass mc, RegHive hDefKey, string sSubKeyName, string sValueName)
        {
            ManagementBaseObject inParams = mc.GetMethodParameters("EnumValues");
            inParams["hDefKey"] = hDefKey;
            inParams["sSubKeyName"] = sSubKeyName;

            ManagementBaseObject outParams = mc.InvokeMethod("EnumValues", inParams, null);

            if (Convert.ToUInt32(outParams["ReturnValue"]) == 0)
            {
                string[] sNames = outParams["sNames"] as String[];
                int[] iTypes = outParams["Types"] as int[];

                for (int i = 0; i < sNames.Length; i++)
                {
                    if (sNames[i] == sValueName)
                    {
                        return (RegType)iTypes[i];
                    }
                }
                // value not found
            }
            else
            {
                // EnumValues call failed
            }
            // Things have fallen apart and EnumValues didn't get us what we wanted so assume it's a string
            return RegType.REG_SZ;
        }
    }
}
4

2 に答える 2

5

わお。OK、これをデバッグするのに何時間も費やしたので、これを StackOverflow に投稿してから 20 分も経たないうちに、自分で問題を見つけました。

頭の片隅では、32 ビット キーと 64 ビット キーを持つ奇妙なハイブリッド レジストリが存在する状況がいくつかあることを知っていました。私が使用していたマシンは両方とも 64 ビットだったので、ここでは当てはまらないと思いました。しかし、私が忘れていたのは、プロジェクト自体に Platform ターゲットを指定する設定があるということでした。

プロジェクトを右クリックし、[プロパティ] に移動します。[ビルド] タブを選択します。次に、プラットフォーム ターゲットを x86 (デフォルトである必要があります) から任意の CPU に変更します。再コンパイルすると、レジストリ クエリは正常に機能します。

于 2012-08-27T05:12:27.857 に答える