2

我有一个运行良好的自定义安装程序,但它每次更新应用程序时都会要求用户获得管理员权限。我正在创建一个跳过此部分的 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));

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

4

2 回答 2

4

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

file.SetAccessControl(access);

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

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

  • 是该集合必须在文件写入之后发生。事先将集合应用于文件是无效的。
于 2011-11-10T18:50:05.410 回答
3

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

我想出了以下小类来帮助解决它,因为做这些事情的 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 资源管理器中查看文件属性的安全选项卡来观察结果。

于 2011-12-14T11:40:24.760 回答