我按照这个C#示例,可以查询一些注册表值,但不能全部查询:
如果我不知道它的类型,如何从远程计算机获取注册表值?(C#)
我可以可靠地获取注册表项,例如CurrentVersion,ProductName等.但是当我尝试获取CSDVersion时,它失败了.
我已经在.NET 2.0和.NET 4.0中编译,但结果相同.我试过查询本地机器和远程机器.两者都能够返回其他注册表值,但不能返回这个特定的值.
两者都是x64机器(Windows 7旗舰版和Windows 2008 R2),因此无论如何都不会出现任何问题.
我发现一个奇怪的事情是EnumValues函数只返回17个值,并且在这个特定的注册表项中有21个.在缺少的四个中,CSDVersion就是其中之一.
我很好奇,如果有人知道为什么这四个值不会回来,但所有其余的都会?缺少价值观:
真正奇怪的是我有另一个用.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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
哇.好的,所以花了几个小时试图调试这个,我在将此问题发布到StackOverflow后不到20分钟就找到了问题.
我知道在我的脑后,有些情况下有一些奇怪的混合注册表,其中有32位和64位密钥.我认为它不适用于此,因为我使用的两台机器都是64位.但我忘记的是项目本身有一个指定平台目标的设置.
右键单击该项目,然后转到"属性".选择"构建"选项卡.然后将平台目标从x86(必须是默认值)更改为任何CPU.重新编译,注册表查询工作正常.
| 归档时间: |
|
| 查看次数: |
1565 次 |
| 最近记录: |