【问题标题】:set file permissions for c:\program files\company\app\file for all users为所有用户设置 c:\program files\company\app\file 的文件权限
【发布时间】:2011-11-10 01:23:38
【问题描述】:

我有一个运行良好的自定义安装程序,但它每次更新应用程序时都会要求用户获得管理员权限。我正在创建一个跳过此部分的 Windows 服务,但 Windows 服务仅授予文件的系统和管理员权限,并且用户无法执行新的更新。

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

FileSecurity access = file.GetAccessControl();
SecurityIdentifier everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
access.AddAccessRule(new FileSystemAccessRule(everyone, FileSystemRights.ReadAndExecute, AccessControlType.Allow));

但设置不生效。我应该从这里做什么?

【问题讨论】:

  • .. but it asks the user for admin permission every time it updates an application. - 不应该吗?
  • 旧方式是的,但是如果您通过已经以管理员身份运行的服务下载,则不会。如果您使用 Google Chrome,它永远不会要求您提供更新权限。检查您的服务是否有 Google Update Service,它会更新 Google Chrome,而不会打扰您请求提升的更新权限。
  • 啊,好吧,就是这样。很高兴知道。

标签: c# windows-services file-security


【解决方案1】:

我想通了。我只需要打电话,

file.SetAccessControl(access);

在上述之后。显然 file.GetAccessControl 会传回访问控制的副本,而不是控制文件权限的副本,直到您使用修改后的权限调用 file.SetAccessControl。

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

  • 是该集合必须在文件写入后发生。事先将集合应用到文件是无效的。

【讨论】:

    【解决方案2】:

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

    我想出了以下小类来帮助解决它,因为用于执行此操作的 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);
        }
    }
    

    调用代码如下:

            _permissionController = new PermissionController(_file);
            _permissionController.Allow(FileSystemRights.Read, FileSystemRights.Write);
            _permissionController.Deny(FileSystemRights.FullControl,
                                       FileSystemRights.Modify,
                                       FileSystemRights.ReadAndExecute);
            _permissionController.Apply();
    

    其中 _file 是完全限定的路径。

    你需要小心调用

    File.SetAccessControl 后添加/删除规则否则无效。

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

    您还需要小心一点,因为允许您拒绝的权利并不等同于删除拒绝该权利的规则。似乎被拒绝的权利覆盖了被允许的权利。

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

    【讨论】:

    • 很好——我不能使用_id = WindowsIdentity.GetCurrent().Owner;因为服务没有所有者,或者至少没有用户。感谢您提供有关必须删除 Denies 的提示,我对此一无所知。
    猜你喜欢
    • 2010-11-14
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 1970-01-01
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多