установите права доступа к файлам для c:program files company app file для всех пользователей

#c# #windows-services #file-security

#c# #windows-службы #файл-безопасность

Вопрос:

У меня есть пользовательская программа установки, которая работала нормально, но она запрашивает у пользователя разрешение администратора каждый раз, когда обновляет приложение. Я создаю службу 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));
  

но настройка не вступает в силу. Что мне делать дальше?

Комментарии:

1. .. but it asks the user for admin permission every time it updates an application. — Разве это не предполагается?

2. По-старому да, но если вы загружаете через службу, которая уже запущена от имени администратора, то нет. Если вы используете Google Chrome, он никогда не запрашивает у вас разрешения на обновление. Проверьте свои службы, Google Update Service которые обновляют Google Chrome, не беспокоя вас запросами на повышенные разрешения для обновления.

3. Ах да, вот как это работает. Полезно знать.

Ответ №1:

Я понял это. Мне просто нужно было вызвать,

 file.SetAccessControl(access);
  

после вышесказанного. По-видимому, файл.GetAccessControl передает обратно копию элемента управления доступом, а не тот, который управляет правами доступа к файлу, пока вы не вызовете file.Установите AccessControl с измененными разрешениями.

Есть еще одно предостережение, которое я обнаружил с другим файлом, в котором создавалась служба 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 — это полный путь.

Вы должны быть осторожны при вызове

Файл.Установите AccessControl после добавления / удаления правил, поскольку в противном случае эффекта не будет.

Если я не неправильно понял API, вы должны добавить правило для каждого разрешения, потому что перечисление FileSystemRights не использует флаги.

Вам также нужно быть немного осторожным, поскольку предоставление права, в котором вы отказали, не эквивалентно удалению правила, которое запрещает это право. Похоже, что запрещенные права переопределяют разрешенные.

Вы можете ознакомиться с результатами, просмотрев вкладку безопасность свойств файла в проводнике Windows.

Комментарии:

1. Это приятно — я не могу использовать _id = WindowsIdentity.GetCurrent().Owner; , потому что у сервиса нет владельца или, по крайней мере, нет пользователя. Спасибо за совет по удалению запретов, я не знал об этом.