使用.NET设置注册表项写入权限

时间:2010-01-27 23:18:14

标签: c# .net winapi permissions registry

我正在尝试在安装过程中向我的应用程序的注册表设置授予对计算机的每个人或所有用户的写访问权限。

我的应用程序在安装后没有直接具有适当的权限,而无需管理员授予它们,即使密钥和值存在,也无法更新?我有下面的代码段,但是由于未经授权的访问/访问被拒绝,安装程序失败了。我想我走在正确的轨道上......

如何在不需要手动关注的情况下解决权限问题?有更好的方法吗?我正在尝试通过添加此功能来替换Visual Studio设置中的其他安装程序。

    protected void GrantAllAccessPermission(String key)
    {
        try
        {
            SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
            NTAccount account = sid.Translate(typeof(NTAccount)) as NTAccount;

            // Get ACL from Windows, allow writing to the registry key
            using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(key, true))
            {

                RegistrySecurity rs = new RegistrySecurity();

                // Creating registry access rule for 'Everyone' NT account
                RegistryAccessRule rar = new RegistryAccessRule(
                    account.ToString(),
                    RegistryRights.FullControl,
                    InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
                    PropagationFlags.None,
                    AccessControlType.Allow);

                rs.AddAccessRule(rar);
                rk.SetAccessControl(rs);
            }

        }
        catch (System.Security.SecurityException ex)
        {
            throw new InstallException(
                String.Format("An exception in GrantAllAccessPermission, security exception! {0}", key),  
                ex);
        }
        catch (UnauthorizedAccessException ex)
        {
            throw new InstallException(
                String.Format("An exception in GrantAllAccessPermission, access denied! {0}", key),  
                ex);
        }

    }

4 个答案:

答案 0 :(得分:10)

我意识到这篇文章有点陈旧,但我认为值得对任何可能偶然发现它的人进行评论,就像我在试图找出类似问题时所做的那样。你非常接近,我刚改变了两行代码。关键变化是第一个;打开密钥时,需要将其打开为可写。第二个更改是附加新权限而不是替换所有权限...因为您授予每个人完全访问权限,所以您不需要进行此更改,但如果您要为单个用户添加权限,则需要附加权限。

我做的每次更改都首先使用// CHANGED:

注释旧行
SecurityIdentifier sid = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
NTAccount account = sid.Translate(typeof(NTAccount)) as NTAccount;

// Get ACL from Windows

// CHANGED to open the key as writable: using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(key))
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(key, RegistryKeyPermissionCheck.ReadWriteSubTree))
{

        // CHANGED to add to existing security: RegistrySecurity rs = new RegistrySecurity();
    RegistrySecurity rs = rk.GetAccessControl()

    // Creating registry access rule for 'Everyone' NT account
    RegistryAccessRule rar = new RegistryAccessRule(
        account.ToString(),
        RegistryRights.FullControl,
        InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
        PropagationFlags.None,
        AccessControlType.Allow);

    rs.AddAccessRule(rar);
    rk.SetAccessControl(rs);
}

答案 1 :(得分:1)

更好的方法是将您的应用程序设置放在用户有权更新的位置。

答案 2 :(得分:1)

我最终采用了一种不同的更好的方法,切换到Wix 3.0。使用Wix安装程序,我可以更轻松地自定义和扩展我的安装。

添加Wix Util Extension命名空间:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
     xmlns:util='http://schemas.microsoft.com/wix/UtilExtension'>

Wix Sample for registry permissions:

<!-- Registry entries -->
<DirectoryRef Id="TARGETDIR">
  <Component Id="RegistryEntries" Guid="{YOUR-GUID}">

    <!-- Create registry keys and grant user rights -->
    <!-- Add Registry Keys and default values as necessary -->
    <RegistryKey Root="HKLM" Key="$(var.RegKey)" Action="create">
        <util:PermissionEx User="[WIX_ACCOUNT_USERS]"  GenericAll="yes"/>
    </RegistryKey> 
    ...

答案 3 :(得分:1)

试试这个

 new   System.Security.Permissions.RegistryPermission(System.Security.Permissions.PermissionState.Unrestricted).Assert();
try
{
//Your code
}catch
{
}finally
{
       System.Security.Permissions.RegistryPermission.RevertAssert();
}
相关问题