C# 为所有用户设置c:\program files\company\app\file的文件权限

C# 为所有用户设置c:\program files\company\app\file的文件权限,c#,windows-services,file-security,C#,Windows Services,File Security,我有一个自定义的安装程序,它工作得很好,但每次更新应用程序时都会向用户请求管理员权限。我正在创建一个跳过此部分的windows服务,但windows服务仅授予系统和管理员对该文件的权限,用户无法执行新的更新 为了纠正这个问题,我正在尝试(在文件下载/安装到正确的位置后(从windows服务中,它的帐户为ServiceAccount.LocalSystem) 但是设置无效。我该怎么办呢?我想好了。我只需要打个电话 file.SetAccessControl(access); 在执行上述操作之后,

我有一个自定义的安装程序,它工作得很好,但每次更新应用程序时都会向用户请求管理员权限。我正在创建一个跳过此部分的windows服务,但windows服务仅授予系统和管理员对该文件的权限,用户无法执行新的更新

为了纠正这个问题,我正在尝试(在文件下载/安装到正确的位置后(从windows服务中,它的帐户为ServiceAccount.LocalSystem)


但是设置无效。我该怎么办呢?

我想好了。我只需要打个电话

file.SetAccessControl(access);
在执行上述操作之后,.file.GetAccessControl会传回访问控制的副本,而不是控制文件权限的副本,直到您使用修改后的权限调用file.SetAccessControl

我在服务在c:\ProgramData中创建的另一个文件中发现了另一个警告

  • 设置必须在写入文件后发生。事先将设置应用于文件无效

我最近在从网络加载文件时遇到了一个问题,希望能够在测试中重新创建该错误,但遇到了同样的问题

我提出了以下小类来帮助解决这个问题,因为做这些事情的API非常可怕,而且充满了小陷阱:

public class PermissionController
{
    private readonly string _file;
    private readonly FileSecurity _accessControl;
    private readonly SecurityIdentifier _id;
    private readonly List<FileSystemAccessRule> _permissionsDenied;

    public PermissionController(string file)
    {
        _file = file;
        _accessControl = File.GetAccessControl(_file);
        _id = WindowsIdentity.GetCurrent().Owner;
        _permissionsDenied = new List<FileSystemAccessRule>();
    }

    public void Allow(params FileSystemRights[] rights)
    {
        foreach (var right in rights)
            AddRule(Rule(right, AccessControlType.Allow));
    }

    public void Deny(params FileSystemRights[] rights)
    {
        foreach (var right in rights)
        {
            var rule = Rule(right, AccessControlType.Deny);
            AddRule(rule);
            _permissionsDenied.Add(rule);
        }
    }

    private void AddRule(FileSystemAccessRule rule)
    {
        _accessControl.AddAccessRule(rule);
    }

    private FileSystemAccessRule Rule(FileSystemRights right, AccessControlType type)
    {
        return new FileSystemAccessRule(_id, right, type);
    }

    public void RemoveDeniedPermissions()
    {
        foreach (var rule in _permissionsDenied)
            _accessControl.RemoveAccessRule(rule);

        Apply();
    }

    public void Apply()
    {
        File.SetAccessControl(_file,_accessControl);
    }
}
其中_file是完全限定路径

你打电话时要小心

File.SetAccessControl在添加/删除规则之后,否则将不起作用

除非我误解了API,否则您必须为每个权限添加一个规则,因为FileSystemRights枚举不使用标志

您还需要小心一点,因为允许您已拒绝的权利并不等于删除拒绝该权利的规则。似乎被拒绝的权利凌驾于允许的权利之上


您可以通过在windows资源管理器中查看文件属性的“安全”选项卡来查看结果。

。但每次更新应用程序时,它都会向用户请求管理员权限。
-这不是应该的吗?老办法是的,但如果您通过已作为管理员运行的服务下载,则不会。如果您使用Google Chrome,它从不要求您提供更新权限。请检查您的服务,以获得
谷歌更新服务
,该服务可以更新谷歌浏览器,而不会因为请求提升更新权限而打扰您。啊,好吧,就是这样。很高兴知道。这很好-我不能使用
\u id=WindowsIdentity.GetCurrent().Owner;
因为服务没有所有者,或者至少没有用户。感谢您提供关于删除拒绝的提示,我不知道这一点。
public class PermissionController
{
    private readonly string _file;
    private readonly FileSecurity _accessControl;
    private readonly SecurityIdentifier _id;
    private readonly List<FileSystemAccessRule> _permissionsDenied;

    public PermissionController(string file)
    {
        _file = file;
        _accessControl = File.GetAccessControl(_file);
        _id = WindowsIdentity.GetCurrent().Owner;
        _permissionsDenied = new List<FileSystemAccessRule>();
    }

    public void Allow(params FileSystemRights[] rights)
    {
        foreach (var right in rights)
            AddRule(Rule(right, AccessControlType.Allow));
    }

    public void Deny(params FileSystemRights[] rights)
    {
        foreach (var right in rights)
        {
            var rule = Rule(right, AccessControlType.Deny);
            AddRule(rule);
            _permissionsDenied.Add(rule);
        }
    }

    private void AddRule(FileSystemAccessRule rule)
    {
        _accessControl.AddAccessRule(rule);
    }

    private FileSystemAccessRule Rule(FileSystemRights right, AccessControlType type)
    {
        return new FileSystemAccessRule(_id, right, type);
    }

    public void RemoveDeniedPermissions()
    {
        foreach (var rule in _permissionsDenied)
            _accessControl.RemoveAccessRule(rule);

        Apply();
    }

    public void Apply()
    {
        File.SetAccessControl(_file,_accessControl);
    }
}
        _permissionController = new PermissionController(_file);
        _permissionController.Allow(FileSystemRights.Read, FileSystemRights.Write);
        _permissionController.Deny(FileSystemRights.FullControl,
                                   FileSystemRights.Modify,
                                   FileSystemRights.ReadAndExecute);
        _permissionController.Apply();