2010-09-22 3 views
7

Sto lavorando a un software che deve copiare un file in una determinata directory sul filesystem. Deve funzionare su entrambi i SO compatibili con UAC (Vista, 7) e XP. Per aggirare il problema della scrittura in una directory in cui è richiesta l'elevazione UAC, l'app avvia effettivamente un altro processo con un manifest che indica che è necessario UAC. Questo genera il prompt e quindi esegue la copia quando l'utente conferma.C# .NET - come determinare se la directory è scrivibile, con o senza UAC?

Da quello che posso vedere, una directory può avere tre diversi stati di autorizzazione logica, scrivibili senza elevazione UAC, scrivibili con elevazione UAC e non scrivibili.

La mia domanda è questa: per una determinata directory, come posso determinare in modo affidabile se l'utente corrente può copiare (e potenzialmente sovrascrivere) un file in quella directory, e se posso, come posso determinare se è richiesta l'elevazione UAC ?

Su XP, questo potrebbe essere semplice come controllare se è concessa l'autorizzazione "Consenti scrittura", ma su Vista/7, ci sono directory in cui questa autorizzazione non è concessa, ma questa azione è ancora possibile con Controllo dell'account utente .

risposta

10

Abbiamo un metodo per WRITEACCESS su file, probabilmente si può adattarlo per Directory (Directory.GetAccessControl e così via)

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

Spero che questo aiuti.

+0

Grazie - Ho appena provato questo, e mentre questo mi dice se posso scrivere sotto l'identità corrente, restituisce false se entrambi gli accessi in scrittura sono esplicitamente negati e se è permesso con un elevazione UAC. Devo differenziare tra queste ultime due situazioni. Lo prenderò come punto di partenza però. – growse

2

È possibile gestire il caso scrivibile senza elevazione solo provando l'operazione. È quando ciò fallisce, e devi distinguere tra non scrivibile e scrivibile tramite elevazione UAC che è potenzialmente difficile.

Non penso che mi piacerebbe che i programmi cercassero di capirlo (dato che spesso si sbagliano molto spesso).

penso che sia giusto per la progettazione con questi presupposti:

  • amministratori a volte gestiscono conti come limitato a software di prova che non si fidano -> se la vostra applicazione sta per apportare modifiche invasive al computer che richiedono UAC che vogliono annullare, non elevare.
  • Gli amministratori elevati possono scrivere il file (dopotutto sono admin) -> non è necessario un controllo ACL effettivo, è sufficiente rilevare un token limitato.
  • Gli utenti possono elevare utilizzando un account diverso o possono chiedere a un collega di completare l'azione richiesta da UAC -> il controllo per il token con restrizioni mancherà a questi casi.
  • Altre cose recuperabili causano l'accesso negato, incluso il file in uso -> a volte la cosa giusta da fare è riprovare usando le stesse autorizzazioni limitate.

Così tutto, vorrei suggerire di provare l'asInvoker operazione, in caso di accesso negato far apparire un messaggio che spiega che Windows ha negato l'operazione, le possibili cause sono: il file in uso, di elevazione richiesto, le credenziali di amministratore richiesto , e dare all'utente tre pulsanti:

  • Annulla
  • Riprova con credenziali correnti
  • (icona scudo) elevare le autorizzazioni e riprovare
+0

Avevo pensato di scendere nel "provare tutto per vedere cosa funziona", ma mi ero chiesto se c'era un modo migliore. Non dovrebbe essere troppo difficile tentare la scrittura come utente corrente, e se fallisce, avvia il processo che porta a UAC. Se fallisce, avvisa che la copia non è possibile. – growse