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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2151074/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:56:30  来源:igfitidea点击:

Setting Registry key write permissions using .NET

c#.netwinapipermissionsregistry

提问by Jared Knipp

I'm trying to grant Write access to my application's registry settings to everyone or all users of a machine during the install process.

我试图在安装过程中向机器的所有人或所有用户授予对我的应用程序注册表设置的写入访问权限。

My application does not have the appropriate permissions directly after install without requiring an administrator to grant them even though the keys and values exists, they cannot be updated? I've the snippet below, but the installer is failing due to Unauthorized access / access denied. I think I'm on the right track...

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

How can I resolve the permissions issue without requiring manual attention? Is there a better approach? I'm attempting to replace an additional installer with the Visual Studio setup by adding this functionality.

如何在不需要手动关注的情况下解决权限问题?有没有更好的方法?我正在尝试通过添加此功能用 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);
        }

    }

采纳答案by Jared Knipp

I ended up taking a different and better approach by switching to Wix 3.0. Using the Wix installer I'm able more easily customize and expand my install.

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

Add Wix Util Extension namespace:

添加 Wix Util 扩展命名空间:

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

Wix Sample for registry permissions:

注册表权限的 Wix 示例:

<!-- 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> 
    ...

回答by dkackman

The better approach is to put your application settings somewhere that your users will have permission to update.

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

回答by KevinC

I realize this post is a bit old but I figured it was worth commenting on it for anyone that might stumble upon it like I did while trying to figure out a similar issue. You were very close, I just changed two lines of code. The key change is the first one; when opening the key you need to open it as writable. The second change is to append new permissions rather than replacing all permissions...since you are giving everyone full access, you don't really need this change, but if you were adding permissions for single user, you would want to append permissions.

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

Each change I made first comments out the old line with //CHANGED:

我所做的每个更改首先用 //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);
}

回答by Tanmay Nehete

try this

尝试这个

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