2012-08-27 74 views
0

的價值我跟着這個C#示例,我能查詢某些註冊表值,但不是所有的人:無法查詢CSDVersion

How to obtain a registry value from a remote machine if I don't know its type? (C#)

我可以可靠地獲取註冊表項,如CURRENTVERSION時, ProductName等,但是當我嘗試獲取CSDVersion時,它失敗了。

我已經在.NET 2.0和.NET 4.0中編譯過,但結果相同。我試過查詢本地機器和遠程機器。兩者都能夠返回其他註冊表值,但不是這個特定的值。

兩者都是x64機器(Windows 7旗艦版和Windows 2008 R2),因此任何方式都不應該有任何問題以任何方式進入註冊表。

我發現的一件奇怪的事情是EnumValues函數只返回17個值,並且在這個特定的註冊表項中有21個值。在失蹤的四個中,CSDVersion就是其中之一。

我很好奇,如果有人知道爲什麼這四個值不會回來,但其餘的都會呢? 缺失值:

  • CSDVersion - REG_SZ
  • DigitalProductID - REG_BINARY
  • DigitalProductId4 - REG_BINARY
  • 的ProductID - 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

哇。好吧,花了幾個小時試圖調試這個,我發現這個問題發佈到StackOverflow後不到20分鐘。

我知道我的腦海裏有些情況,那裏有一些奇怪的32位和64位密鑰的混合註冊表。我不認爲它適用於這裏,因爲我使用的兩臺機器都是64位。但是我忘記了項目本身有一個指定平臺目標的設置。

右鍵單擊該項目,然後轉到屬性。選擇生成選項卡。然後將平臺目標從x86(必須是默認值)更改爲任何CPU。重新編譯,並且註冊表查詢工作得很好。

+0

有趣。這意味着強制x86進程無法可靠地確定其系統環境。 – ygoe