2010-09-22 2 views
7

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

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

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

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

ответ

10

У нас есть метод 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); 
    } 

Надеется, что это помогает.

+0

Спасибо - я только что протестировал это, и пока это говорит мне, могу ли я писать под текущим идентификатором, он возвращает false, если явно запрещен доступ к записи, а также разрешен с увеличением UAC. Мне нужно провести различие между этими двумя последними ситуациями. Я возьму это как отправную точку. – growse

2

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

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

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

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

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

  • Отменить
  • Retry с текущими учетными данными
  • (значок щита) Поднимают разрешения и повторите
+0

Я подумал о том, чтобы спуститься по «попробуйте все, чтобы увидеть, что работает», но задался вопросом, есть ли лучший способ. Не должно быть слишком сложно попытаться записать как текущего пользователя, и если это не удастся запустить процесс, который поднимается до UAC. Если это не удается, сообщите, что копия невозможна. – growse

Смежные вопросы