通过C#从注册表中的“UserChoice”键中删除一个“拒绝”规则(权限)。

5

我正在处理文件关联问题。我已经确定在以下位置有一个名为UserChoice的键:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\[ext].

我已经能够读取和写入UserChoice键,但前提是我必须先创建它,并且它还没有被Windows创建。但是,如果UserChoice键已经被Windows创建,那么我需要以管理员身份运行才能访问该键。我的最终目标是删除UserChoice键。
我注意到Windows在UserChoice键上设置了一个拒绝(Deny)规则,这阻止了我删除该键。如果我能成功移除该规则,我相信我就能删除UserChoice键。以下是我尝试的代码:
public static void ShowSecurity(RegistryKey regKeyRoot, string user) {
    RegistrySecurity security = regKeyRoot.GetAccessControl(AccessControlSections.All);

    foreach (RegistryAccessRule ar in
        security.GetAccessRules(true, true, typeof(NTAccount))) {

        if (ar.IdentityReference.Value.Contains(User) &&
                ar.AccessControlType.ToString().ToLower() == "deny") {

            security.RemoveAccessRuleSpecific(ar);
            regKeyRoot.SetAccessControl(security);
        }
    }
}

当 Windows 创建 UserChoice 键时,它为当前用户添加了一个类型为 Deny;权限:Special 的安全规则。此规则不会被继承,仅适用于 UserChoice 键。
通过一些操作并以管理员身份运行,我能够访问该 RegistryAccessRule。但是即使以管理员身份运行,我也无法删除此规则。在我的研究中,我曾经读到过没有程序化的方法可以做到这一点。我可以通过 RegEdit 删除此规则。我还可以使用 NirSoft 的文件类型管理器删除 UserChoice 键。因此我认为应该有某种方法可以做到这一点。
总结: 是否有办法删除拒绝规则,以便我可以删除 UserChoice 键?

有人找到了解决方法吗?我也遇到了同样的问题。 - Jason
很遗憾,据我所知还没有。我已经对此进行了更多的工作,但我认为它需要非托管代码。 - ScruffyDuck
@ScruffyDuck,你的代码绝对是正确的方向。你的代码和ali的答案提供的修改后的代码让我成功了。不需要使用非托管代码。请参见我的答案 - DavidRR
3个回答

2

您的代码示例和@ali在答案中提出的修订建议,启发了我对克服Windows对UserChoice键设置的安全限制的解决方案,这使我能够删除该键。

我的解决方案假定UserChoice键存在于HKEY_CURRENT_USER (HKCU) hive中。如果是这种情况,则用户拥有UserChoice键,因此具有更改该键的安全设置以及最终删除它所需的必要权限。(这意味着用户无需成为管理员组的成员。)

此方法的extensionKey参数是UserChoice键的父键。

static void DeleteUserChoiceKey(RegistryKey extensionKey)
{
    const string userChoiceKeyName = "UserChoice";

    using (RegistryKey userChoiceKey =
        extensionKey.OpenSubKey(userChoiceKeyName,
            RegistryKeyPermissionCheck.ReadWriteSubTree,
            RegistryRights.ChangePermissions))
    {
        if (userChoiceKey == null) { return; }
        string userName = WindowsIdentity.GetCurrent().Name;
        RegistrySecurity security = userChoiceKey.GetAccessControl();

        AuthorizationRuleCollection accRules =
            security.GetAccessRules(true, true, typeof(NTAccount));

        foreach (RegistryAccessRule ar in accRules)
        {
            if (ar.IdentityReference.Value == userName &&
                ar.AccessControlType == AccessControlType.Deny)
            {
                security.RemoveAccessRuleSpecific(ar); // remove the 'Deny' permission
            }
        }

        userChoiceKey.SetAccessControl(security); // restore all original permissions
                                                  // *except* for the 'Deny' permission
    }

    extensionKey.DeleteSubKeyTree(userChoiceKeyName, true);
}

0
public static void ShowSecurity(RegistryKey regKeyRoot, string user) 
{

regKeyRoot.OpenSubKey("", RegistryKeyPermissionCheck.ReadWriteSubTree,
                    RegistryRights.ChangePermissions);

RegistrySecurity security = regKeyRoot.GetAccessControl(AccessControlSections.All);

security.SetGroup( new NTAccount("Administrators") );
security.SetOwner( new NTAccount("ali") ); //Your account name
security.SetAccessRuleProtection(true, false);
regKeyRoot.SetAccessControl(security);

//---------

  foreach (RegistryAccessRule ar in security.GetAccessRules(true, true, typeof(NTAccount))) 
  {
    if (ar.IdentityReference.Value.Contains(User) && ar.AccessControlType ==  AccessControlType.Deny )
       security.RemoveAccessRuleSpecific(ar);
  }

regKeyRoot.SetAccessControl(security);


}

0
一个快速的想法。在更改规则之前,如果您拥有regKey的所有权,它是否有效?

你能详细说明一下吗?谢谢。 - ScruffyDuck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接