2010-09-22 14 views
7

Estoy trabajando en una pieza de software que necesita copiar un archivo a un directorio determinado en el sistema de archivos. Debe funcionar tanto en sistemas operativos con reconocimiento de UAC (Vista, 7) como en XP. Para evitar el problema de escribir en un directorio donde se requiere la elevación de UAC, la aplicación realmente inicia otro proceso con un manifiesto que establece que se requiere UAC. Esto genera el mensaje y luego hace la copia cuando el usuario confirma.C# .NET - cómo determinar si el directorio es grabable, con o sin UAC?

Por lo que puedo ver, un directorio puede tener tres estados de permisos lógicos diferentes: grabable sin elevación UAC, escribible con elevación UAC y no grabable.

Mi pregunta es esta: para un directorio determinado, ¿cómo puedo determinar de manera confiable si el usuario actual puede copiar (y potencialmente sobreescribir) un archivo en ese directorio, y si puedo, cómo puedo determinar si es necesaria la elevación de UAC ?

En XP, esto podría ser tan simple como comprobar si se concede el permiso 'Permitir escritura', pero en Vista/7, hay directorios donde no se concede este permiso, pero esta acción aún es posible con UAC .

Respuesta

10

tenemos un método para WRITEACCESS de archivos, es probable que pueda adaptarlo a directorios (Directory.GetAccessControl y así sucesivamente)

/// <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); 
    } 

Espero que esto ayude.

+0

Gracias - Acabo de probar esto, y aunque esto me dice si puedo escribir con la identidad actual, devuelve falso si tanto el acceso de escritura está explícitamente denegado como si está permitido con una elevación UAC. Necesito diferenciar entre estas dos últimas situaciones. Sin embargo, lo tomaré como punto de partida. – growse

2

Usted maneja la capacidad de escritura sin elevación con tan solo intentar la operación. Es cuando eso falla, y usted tiene que distinguir entre escritura no grabable y escritura a través de la elevación UAC que es potencialmente difícil.

No creo que me gustaría que los programas intenten darme cuenta de eso (ya que inevitablemente se equivocarán bastante a menudo).

creo que es seguro para diseñarlo con estos supuestos:

  • ocasiones, los administradores ejecutar cuentas como Restringida para el software de prueba que no confían en -> si su aplicación va a realizar cambios invasoras a la computadora que requieren UAC que desean cancelar, no elevar.
  • Los administradores elevados pueden escribir el archivo (son administradores después de todo) -> no es necesario realizar una verificación de ACL real, detectar un token restringido es suficiente.
  • Los usuarios pueden elevarse usando una cuenta diferente, o pueden pedirle a un compañero de trabajo que complete la acción requerida por UAC -> la comprobación del token restringido no detectará estos casos.
  • Otros elementos recuperables provocan el acceso denegado, incluido el archivo en uso -> a veces lo correcto es volver a intentarlo con los mismos permisos restringidos.

Así que en total, sugeriría probar la asInvoker operación, en caso de denegación de acceso que aparezca un mensaje que explica que Windows negó la operación, las causas posibles son: archivo en uso, la elevación requerida, credenciales de administrador requiere y dar al usuario tres botones:

  • Cancelar
  • reintento con credenciales actuales
  • (icono de escudo) elevar los permisos y vuelva a intentar
+0

Pensé en bajar el enfoque de "probar todo para ver qué funciona", pero me pregunté si habría una manera mejor. No debería ser demasiado difícil intentar escribir como el usuario actual, y si eso falla, se inicia el proceso que se eleva a UAC. Si eso falla, advierta que la copia no es posible. – growse

Cuestiones relacionadas