我需要在C#中备份一个注册表项。我一直在尝试P/调用RegSaveKey,但无济于事。由于无法关闭组策略设置,我无法使用"Reg.exe“备份注册表。
下面是所有的代码:
private static UIntPtr GetKey(string registryPath)
{
UIntPtr hKey = UIntPtr.Zero;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, registryPath, 0, KEY_READ, out hKey) != 0)
{
throw new Exception("Error getting key!");
}
return hKey;
}
private static void ExportRegistry(string registryPath)
{
UIntPtr key = UIntPtr.Zero;
try
{
key = GetKey(registryPath);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return;
}
if (key == UIntPtr.Zero)
{
Console.WriteLine("Not key to export!");
return;
}
try
{
RegSaveKey(key, "c:\\temp\\test.reg", IntPtr.Zero);
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
if (key != UIntPtr.Zero)
{
RegCloseKey(key);
}
}
private static int KEY_READ = 131097;
private static UIntPtr HKEY_LOCAL_MACHINE = new UIntPtr(0x80000002u);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegCloseKey(UIntPtr hKey);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegOpenKeyEx(UIntPtr hKey, string subKey, int ulOptions, int samDesired, out UIntPtr hkResult);
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern uint RegSaveKey(UIntPtr hKey, string lpFile, IntPtr lpSecurityAttributes);
发布于 2013-02-02 02:26:43
您似乎没有检查RegOpenKeyEx或RegSaveKey的返回值是否存在错误。我怀疑您得到的返回值是ERROR_PRIVILEGE_NOT_HELD。注册表函数不使用SetLastError,它们直接返回它。实际上,对于每个Win32应用程序接口调用,必须检查返回值是否为。
无论您的SE_BACKUP_NAME访问级别如何,RegSaveKey都需要启用ACL权限。因此,您需要在调用RegSaveKey之前添加代码来启用此权限,然后在调用完成后禁用它。
这是另一个有更多信息的question,我相信还有其他的。
发布于 2013-02-02 03:08:55
首先,我想评论一下,你的问题忽略了一些非常重要的细节。也就是说,你实际上没有给出任何关于你的代码是如何失败的信息。你所说的就是:
我一直在尝试P/
RegSaveKey,但都没有用。
像这样的问题都是关于细节的。我们需要查看精确和详细的错误诊断信息。请记住,我们看不到您的屏幕。
您需要更加关注API调用的返回值。您正在检查RegOpenKeyEx
的返回值是否为零,但仅此而已。您需要捕获并检查RegOpenKeyEx
返回的值。这是一个错误代码。如果错误代码不等于零,则可以抛出Win32Exception
。
int err = RegOpenKeyEx(...);
if (err != 0)
throw new Win32Exception(err);
更改代码以抛出Win32Exception
,当错误发生时,您至少会获得一些信息性文本。因此,如果RegOpenKeyEx
失败了,您至少可以找出原因。
而且您根本没有检查其他API调用。给他们同样的待遇。
对于您对RegOpenKeyEx
的调用,失败模式真的很少。我能编造的唯一合理的解释是注册表项不存在。我想你已经检查过了。但要当心registry redirector。如果您的进程是在64位操作系统上运行的32位进程,则重定向器会将您带到注册表的WOW6432Node
部分,即32位视图。也许您所说的“无用”的意思是将信息保存到文件中,但这是错误的信息。这与注册表重定向器混淆您的情况是一致的。
如果这就是您的问题所在,那么在调用RegOpenKeyEx
时包括KEY_WOW64_64KEY
标志。或者以x64为目标。
使用RegistryKey
打开密钥会容易得多。我知道你不能很容易地调用RegSaveKey
,所以你仍然需要p/调用它。但是RegistryKey
公开了一个可以传递给RegSaveKey
的Handle
属性。这有一个前提条件。如果您确实需要使用KEY_WOW64_64KEY
标志,则需要.net 4和RegistryView
。
至于RegSaveKey
,我尊重斯蒂芬在他的回答中给出的信息。
https://stackoverflow.com/questions/14649449
复制相似问题