c# - 如何以编程方式将注册表项的所有权授予管理员?

标签 c# .net windows permissions registry

当我将一些机器升级到 Windows 10 时,我遇到了一个奇怪的问题,即 RuntimeBroker 上的不正确权限导致了问题。我找到了 a solution online建议更改权限(首先在注册表中,然后在 DCOM 配置中),我正在尝试编写一个小型 .NET 应用程序来自动执行该过程。

目前相关注册表项的所有者是 NT SERVICE\TrustedInstaller,我正在尝试将其更改为 COMPUTER\Administrators。我有一个简单的 WPF 应用程序,其 requestedExecutionLevel 设置为“requireAdministrator”,但我仍然遇到问题。下面是一段代码来说明问题:

using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.Win32;

namespace PermissionFixer
{
    public class Fixer
    {
        public void Fix()
        {
            var subKey = Registry.ClassesRoot.OpenSubKey(@"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", true);
            if (subKey != null)
            {
                var admins = new NTAccount("Administrators");
                var ac = subKey.GetAccessControl();
                ac.SetOwner(admins);
                ac.AddAccessRule(new RegistryAccessRule(admins, RegistryRights.FullControl, AccessControlType.Allow));
                subKey.SetAccessControl(ac);
            }
        }
    }
}

问题在于,它甚至没有通过对 OpenSubKey() 的调用,就遇到了一个显示“不允许请求的注册表访问”的 SecurityException。我认为那是因为管理员还没有访问权限(记住它属于 TrustedInstaller),但这有点像先有鸡还是先有蛋的问题。奇怪的是,当我手动使用 regedit 时,我 被允许将所有者更改为管理员,而且我很确定我的 regedit 实例正在以管理员身份运行。

我怎样才能让它在 .NET 中工作?

最佳答案

我想通了,幸运的是,可以使用 .NET 类来实现。以下是您必须如何调用 OpenSubKey:

var subKey = Registry.ClassesRoot.OpenSubKey(@"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);

然后你必须取消对 AddAccessRule() 的调用...你不能修改它直到你拥有所有权;并且您必须连续执行这两个操作。所以先获取所有权,然后重新打开具有不同访问权限的 key 以添加访问规则。

编辑:我今天发现您必须首先通过挂接到 P/Invoke 调用来操作运行您的应用程序的 token 。我在 another Stack Overflow question 中找到了一个名为 TokenManipulator 的类.在您的项目中包含该类,然后在调用 OpenSubKey 之前向您的 token 授予 Backup、Restore 和 TakeOwnership 权限。所以你的方法最终会看起来像这样:

try
{
    TokenManipulator.AddPrivilege("SeRestorePrivilege");
    TokenManipulator.AddPrivilege("SeBackupPrivilege");
    TokenManipulator.AddPrivilege("SeTakeOwnershipPrivilege");

    var subKey = Registry.ClassesRoot.OpenSubKey(@"AppID\{9CA88EE3-ACB7-47c8-AFC4-AB702511C276}", RegistryKeyPermissionCheck.ReadWriteSubTree, RegistryRights.TakeOwnership);
    // code to change owner...
}
finally
{
    TokenManipulator.RemovePrivilege("SeRestorePrivilege");
    TokenManipulator.RemovePrivilege("SeBackupPrivilege");
    TokenManipulator.RemovePrivilege("SeTakeOwnershipPrivilege");
}

关于c# - 如何以编程方式将注册表项的所有权授予管理员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38448390/

相关文章:

c# - MVC 3 Razor View,在另一个项目中使用实体模型

c# - 如何支持在 Internet Explorer 64 位浏览器中显示 PDF 文件

c# - 段控制上的 iOS 捕获选择

c# - 我们如何在 asp.net 应用程序中单击按钮清除服务器端缓存?

c++ - 读取应用程序的 list 文件?

c++ - 从VS2013构建XP驱动程序

windows - 如何使用 node.js 服务器在 MS Windows 上移动鼠标光标?

c# - Windows应用程序问题的数组总和

c# - 在参数中使用 Unicode 字符的 Windows 中使用 GhostScript 9.10

.net - 如何将可移植类库 (PCL) 转换为普通类库?