如何以编程方式为管理员提供注册表项的所有权?

时间:2016-07-19 01:53:37

标签: 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的电话,而{34}表示不允许请求注册表访问。&#34;我认为这是因为管理员还没有访问权限(记住它属于TrustedInstaller),但它变成了鸡蛋和鸡蛋的问题。奇怪的是,当我手动使用regedit时,允许将所有者更改为管理员,并且我非常确定我的regedit实例是作为管理员运行的。< / p>

如何在.NET中使用它?

1 个答案:

答案 0 :(得分:3)

我想通了,幸运的是,可以用.NET类实现。以下是调用OpenSubKey的方法:

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

然后你必须把这个电话改为AddAccessRule() ......在你拥有所有权之前你不能修改它;你必须连续进行这两项操作。因此,首先获取所有权,然后重新打开具有不同访问权限的密钥以添加访问规则。

编辑我今天发现,必须首先通过挂钩P / Invoke调用来操作运行应用程序的令牌。我在another Stack Overflow question中找到了一个名为TokenManipulator的类。在项目中包含该类,然后在调用OpenSubKey之前为您的令牌授予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");
}