C#WPF-即使具有管理员权限,也不允许访问注册表?

C#WPF-即使具有管理员权限,也不允许访问注册表?,c#,wpf,windows,registry,administrator,C#,Wpf,Windows,Registry,Administrator,我最近一直在开发一个非常好的注册表编辑器 但是,下面在Regedit中指出的某些注册表项不会显示在我的程序中,因为它们在打开时会引发权限不足的错误,因此会被错误处理捕获并跳过: Regedit: 我的节目: 如您所见,安全密钥丢失,SAM密钥不可扩展,即使我以管理员权限运行该程序 显然,可以通过制作假键并将其放在那里,然后为其显示一个空的默认值来解决这一问题,但这不是一个具体的解决方案,只是一种让用户觉得问题已经解决的方法 我想知道是否有一种方法可以以具体的方式解决这个问题,或者换句话说,接

我最近一直在开发一个非常好的注册表编辑器

但是,下面在Regedit中指出的某些注册表项不会显示在我的程序中,因为它们在打开时会引发权限不足的错误,因此会被错误处理捕获并跳过:

Regedit:

我的节目:

如您所见,安全密钥丢失,SAM密钥不可扩展,即使我以管理员权限运行该程序

显然,可以通过制作假键并将其放在那里,然后为其显示一个空的默认值来解决这一问题,但这不是一个具体的解决方案,只是一种让用户觉得问题已经解决的方法

我想知道是否有一种方法可以以具体的方式解决这个问题,或者换句话说,接受对这些键的注册表访问

它们所显示的只是一个空的默认值,包括可扩展的SAM键——它只有一个名为“SAM”的子键以及一个空的默认值

然而,对于用户来说,如果程序的显示与Regedit中的显示完全相同,那就更好了,因为这意味着它是一个功能齐全的软件

谢谢你的帮助

编辑(包括代码):


您没有向例程提供示例代码,但我怀疑您正在使用默认的注册表安全描述符

调用RegCreateKeyEx或RegSetKeySecurity函数时,可以为注册表项指定安全描述符

调用RegOpenKeyEx函数时,系统会根据密钥的安全描述符检查请求的访问权限。如果用户没有对注册表项的正确访问权限,则打开操作将失败。如果管理员需要访问注册表项,解决方案是启用SE_TAKE_OWNERSHIP_NAME特权,并使用WRITE_OWNER访问权限打开注册表项

此信息取自:MSDN:

在C#中,您应该使用Registry权限类

有关如何处理注册表权限的示例,请参见:

您需要启用
SE\u RESTORE\u特权
SE\u BACKUP\u特权
并使用或与
REG\u选项\u BACKUP\u RESTORE
标志(但这项工作仅从Windows 7和更高版本的Windows开始)

如果设置了此标志,函数将忽略所需参数,并 尝试以备份或还原所需的访问权限打开密钥 钥匙。如果调用线程具有SE_BACKUP_NAME权限 启用后,使用ACCESS_SYSTEM_SECURITY和 密钥\u读取访问权限。如果调用线程具有seu RESTORE\u名称 特权已启用,从Windows Vista开始,密钥已打开 使用ACCESS_SYSTEM_SECURITY,删除并键入写入访问权限。 如果启用了这两种权限,则密钥具有组合访问权限 两种特权


比如说

#define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT}
#define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{
#define END_PRIVILEGES }};

ULONG AdjustBackupRestore()
{
    HANDLE hToken;
    if (OpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
    {
        BEGIN_PRIVILEGES(tp, 2)
            LAA(SE_RESTORE_PRIVILEGE),
            LAA(SE_BACKUP_PRIVILEGE),
        END_PRIVILEGES

        AdjustTokenPrivileges(hToken, FALSE, (::PTOKEN_PRIVILEGES)&tp, 0, 0, 0);
        ULONG err = GetLastError();
        CloseHandle(hToken);

        return err;
    }

    return GetLastError();
}

然而,为了获得注册表编辑器/查看器的全部功能,我必须使用本机api


我已经编辑了一些代码,这些代码包含了在扩展键和创建键时使用的代码。我正在使用RegistryKey.OpenSubKey(subkey)如何使用RegCreateKeyEx?@Aleksbg我又添加了几个链接,解释了如何在.NET中处理注册表安全性。第三个链接显示了C#中的一个示例,它应该对您有所帮助。祝你好运
#define LAA(se) {{se},SE_PRIVILEGE_ENABLED|SE_PRIVILEGE_ENABLED_BY_DEFAULT}
#define BEGIN_PRIVILEGES(tp, n) static const struct {ULONG PrivilegeCount;LUID_AND_ATTRIBUTES Privileges[n];} tp = {n,{
#define END_PRIVILEGES }};

ULONG AdjustBackupRestore()
{
    HANDLE hToken;
    if (OpenProcessToken(NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
    {
        BEGIN_PRIVILEGES(tp, 2)
            LAA(SE_RESTORE_PRIVILEGE),
            LAA(SE_BACKUP_PRIVILEGE),
        END_PRIVILEGES

        AdjustTokenPrivileges(hToken, FALSE, (::PTOKEN_PRIVILEGES)&tp, 0, 0, 0);
        ULONG err = GetLastError();
        CloseHandle(hToken);

        return err;
    }

    return GetLastError();
}
if (!AdjustBackupRestore())//called once on startup
{
    HKEY hKey;
    if (!RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SECURITY\\SAM", REG_OPTION_BACKUP_RESTORE|REG_OPTION_OPEN_LINK, 0, &hKey))
    {
        RegCloseKey(hKey);
    }
}