2010-09-22 5 views
7

Je travaille sur un logiciel qui doit copier un fichier dans un répertoire donné du système de fichiers. Il doit fonctionner sur les deux systèmes d'exploitation UAC (Vista, 7) ainsi que XP. Pour contourner le problème de l'écriture dans un répertoire où l'élévation de l'UAC est requise, l'application lance un autre processus avec un manifeste indiquant que l'UAC est requis. Cela génère l'invite et effectue ensuite la copie lorsque l'utilisateur confirme. D'après ce que je peux voir, un répertoire peut avoir trois différents états d'autorisation logiques - inscriptible sans élévation d'UAC, inscriptible avec l'élévation d'UAC et non inscriptible. Ma question est la suivante: Pour un répertoire donné, comment déterminer de manière fiable si l'utilisateur actuel peut copier (et potentiellement écraser) un fichier dans ce répertoire, et si je le peux, comment déterminer si l'élévation d'UAC est requise ? Sur XP, cela peut être aussi simple que de vérifier si l'autorisation 'Allow Write' est accordée, mais sur Vista/7, il y a des répertoires où cette permission n'est pas accordée, mais cette action est toujours possible avec UAC .C# .NET - comment déterminer si le répertoire est accessible en écriture, avec ou sans UAC?

Répondre

10

Nous avons une méthode pour WRITEACCESS sur les fichiers, vous pouvez probablement l'adapter pour les répertoires (Directory.GetAccessControl etc.)

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

Hope this helps.

+0

Merci - Je viens de tester cela, et alors que cela me dit si je peux écrire sous l'identité actuelle, il renvoie faux si les deux accès en écriture est explicitement refusé ainsi que si elle est autorisée avec une élévation UAC. Je dois faire la différence entre ces deux dernières situations. Je vais prendre comme point de départ cependant. – growse

2

Vous manipulez le dossier inscriptible sans élévation simplement en essayant l'opération. C'est quand cela échoue, et vous devez faire la distinction entre non-inscriptible ou inscriptible via l'élévation UAC qui est potentiellement difficile.

Je ne pense pas que je voudrais que les programmes essayent de comprendre cela pour moi (puisqu'ils vont inévitablement se tromper souvent).

Je pense qu'il est sûr de concevoir avec ces hypothèses:

  • Les administrateurs exécutent parfois des comptes restreints aux logiciels d'essai, ils ne font pas confiance -> si votre application va apporter des modifications invasives à l'ordinateur UAC qu'ils veulent annuler, ne pas élever.
  • Les administrateurs élevés peuvent écrire le fichier (ils sont administrateurs après tout) -> pas besoin d'une vérification ACL réelle, la détection d'un jeton restreint est suffisante.
  • Les utilisateurs peuvent utiliser un autre compte ou demander à un collègue de terminer l'action requise par l'UAC -> la vérification du jeton restreint manquera ces cas.
  • D'autres choses récupérables empêchent l'accès, y compris le fichier en cours d'utilisation -> parfois, la bonne chose à faire est de réessayer en utilisant les mêmes permissions restreintes.

donc tout à fait, je suggère d'essayer la asInvoker de fonctionnement, en cas de refus d'accès apporter une invite qui explique que Windows a nié l'opération, les causes possibles sont les suivants: fichier en cours d'utilisation, l'élévation nécessaire, les informations d'identification d'administrateur requis et donner les trois boutons utilisateur:

  • Annuler
  • Retry avec des informations d'identification actuelles
  • (icône du bouclier) et une nouvelle tentative Élevez autorisations
+0

J'avais envisagé de descendre le "essayer tout pour voir ce qui fonctionne" approche, mais je me demandais s'il y avait une meilleure façon. Il ne devrait pas être trop difficile de tenter l'écriture en tant qu'utilisateur actuel, et si cela échoue, déclenchez le processus qui mène à l'UAC. Si cela échoue, signalez que la copie est impossible. – growse

Questions connexes