C # .NET - как определить, доступен ли каталог для записи, с UAC или без? - PullRequest
7 голосов
/ 22 сентября 2010

Я работаю над программным обеспечением, которому нужно скопировать файл в заданный каталог файловой системы. Он должен работать как с ОС UAC (Vista, 7), так и с XP. Чтобы обойти проблему записи в каталог, где требуется повышение уровня UAC, приложение фактически запускает другой процесс с манифестом, в котором говорится, что требуется UAC. Это создает приглашение, а затем делает копию, когда пользователь подтверждает.

Из того, что я вижу, каталог может иметь три различных логических состояния разрешений - для записи без повышения UAC, для записи с повышением UAC и без записи.

У меня такой вопрос: как для данного каталога надежно определить, может ли текущий пользователь скопировать (и потенциально перезаписать) файл в этот каталог, и если я могу, как определить, требуется ли повышение уровня UAC?

В XP это может быть так же просто, как проверить, предоставлено ли разрешение «Разрешить запись», но в Vista / 7 есть каталоги, где это разрешение не предоставляется, но это действие все еще возможно с UAC.

Ответы [ 2 ]

11 голосов
/ 22 сентября 2010

У нас есть метод WriteAccess для файлов, вы, вероятно, можете адаптировать его для каталогов (Directory.GetAccessControl и т. Д.)

    /// <summary> Checks for write access for the given file.
    /// </summary>
    /// <param name="fileName">The filename.</param>
    /// <returns>true, if write access is allowed, otherwise false</returns>
    public static bool WriteAccess(string fileName)
    {
        if ((File.GetAttributes(fileName) & FileAttributes.ReadOnly) != 0)
            return false;

        // Get the access rules of the specified files (user groups and user names that have access to the file)
        var rules = File.GetAccessControl(fileName).GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier));

        // Get the identity of the current user and the groups that the user is in.
        var groups = WindowsIdentity.GetCurrent().Groups;
        string sidCurrentUser = WindowsIdentity.GetCurrent().User.Value;

        // Check if writing to the file is explicitly denied for this user or a group the user is in.
        if (rules.OfType<FileSystemAccessRule>().Any(r => (groups.Contains(r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Deny && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData))
            return false;

        // Check if writing is allowed
        return rules.OfType<FileSystemAccessRule>().Any(r => (groups.Contains(r.IdentityReference) || r.IdentityReference.Value == sidCurrentUser) && r.AccessControlType == AccessControlType.Allow && (r.FileSystemRights & FileSystemRights.WriteData) == FileSystemRights.WriteData);
    }

Надеюсь, это поможет.

2 голосов
/ 22 сентября 2010

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

Я не думаю, что я хотел бы, чтобы программы пытались выяснить это для меня (так как ония буду часто ошибаться).

Я думаю, что безопасно проектировать его с такими предположениями:

  • Администраторы иногда запускают учетные записи с ограниченным доступом для пробного программного обеспечения, которому они не доверяют-> если ваше приложение собирается внести инвазивные изменения в компьютер, для которого требуется UAC, который они хотят отменить, а не повысить.
  • Опытные администраторы могут записать файл (в конце концов, они администратор) -> нет необходимостифактической проверки ACL, обнаружения ограниченного токена достаточно.
  • Пользователи могут повысить привилегию, используя другую учетную запись, или могут попросить коллегу выполнить действие, требуемое UAC -> проверка ограниченного токена пропустит эти случаи.
  • Другие восстанавливаемые вещи приводят к отказу в доступе, включая используемый файл -> иногда это правильноДля этого нужно повторить попытку, используя те же ограниченные права доступа.

Итак, в целом, я бы предложил попробовать операцию AsInvoker, в случае отказа в доступе вызвать запрос, объясняющий, что Windows отказала в операции, возможные причиныявляются: используемый файл, требуется повышение прав, необходимы учетные данные администратора и предоставляют пользователю три кнопки:

  • Отмена
  • Повторите попытку с текущими учетными данными
  • (щитicon) Поднимите разрешения и повторите попытку
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...