首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >不带Reg.exe的C#中的备份注册表项

不带Reg.exe的C#中的备份注册表项
EN

Stack Overflow用户
提问于 2013-02-01 23:21:27
回答 2查看 2.9K关注 0票数 0

我需要在C#中备份一个注册表项。我一直在尝试P/调用RegSaveKey,但无济于事。由于无法关闭组策略设置,我无法使用"Reg.exe“备份注册表。

下面是所有的代码:

代码语言:javascript
运行
复制
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);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-02 02:26:43

您似乎没有检查RegOpenKeyEx或RegSaveKey的返回值是否存在错误。我怀疑您得到的返回值是ERROR_PRIVILEGE_NOT_HELD。注册表函数不使用SetLastError,它们直接返回它。实际上,对于每个Win32应用程序接口调用,必须检查返回值是否为

无论您的SE_BACKUP_NAME访问级别如何,RegSaveKey都需要启用ACL权限。因此,您需要在调用RegSaveKey之前添加代码来启用此权限,然后在调用完成后禁用它。

这是另一个有更多信息的question,我相信还有其他的。

票数 2
EN

Stack Overflow用户

发布于 2013-02-02 03:08:55

首先,我想评论一下,你的问题忽略了一些非常重要的细节。也就是说,你实际上没有给出任何关于你的代码是如何失败的信息。你所说的就是:

我一直在尝试P/

RegSaveKey,但都没有用。

像这样的问题都是关于细节的。我们需要查看精确和详细的错误诊断信息。请记住,我们看不到您的屏幕。

您需要更加关注API调用的返回值。您正在检查RegOpenKeyEx的返回值是否为零,但仅此而已。您需要捕获并检查RegOpenKeyEx返回的值。这是一个错误代码。如果错误代码不等于零,则可以抛出Win32Exception

代码语言:javascript
运行
复制
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公开了一个可以传递给RegSaveKeyHandle属性。这有一个前提条件。如果您确实需要使用KEY_WOW64_64KEY标志,则需要.net 4和RegistryView

至于RegSaveKey,我尊重斯蒂芬在他的回答中给出的信息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14649449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档