Impossible de copier le fichier, même si FileIOPermission est accordé en C#

J'ai essayé la FileIOPermission dans Windows 7 .NET 3.5. J'ai été un utilisateur de Windows XP et a obtenu cette permission que j'ai été un administrateur

J'ai écrit le code suivant, test pour voir si je pouvais écrire à C:\Program Files\Outlook......

static void Main(string[] args)
{
    Console.WriteLine("Am I an administrator? " + new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);

    // Try and open a file in C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll
    string path = @"C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll";

    try
    {
        FileIOPermission ioPerm = new FileIOPermission(FileIOPermissionAccess.Read, path);
        ioPerm.Demand();

        string backupPath = Path.ChangeExtension(path, ".bak");
        FileIOPermission writeAccess = new FileIOPermission(FileIOPermissionAccess.AllAccess, backupPath);
        writeAccess.Demand();

        Console.WriteLine("Read access is permitted: {0} => {1}",path,SecurityManager.IsGranted(ioPerm));
        Console.WriteLine("Write backup file is permitted: {0} => {1}", backupPath, SecurityManager.IsGranted(writeAccess));

        File.Copy(path, backupPath);

        Console.WriteLine("File copied! {0}",backupPath);
        Console.WriteLine("Deleting file.....");
        File.Delete(path);
    }
    catch (UnauthorizedAccessException uae)
    {
        Console.WriteLine(uae.ToString());
    }

    Console.ReadLine();
}

De sorte que le programme provoque une UnauthorizedAccessException (je m'y attendais), mais ce que je ne comprends pas, c'est que le Demand() permet à l'autorisation, SecurityManager confirme que l'autorisation est accordée, mais lors de l'exécution de la File.Copy() je ne reçois pas l'exception.

Bien que je suis heureux de voir .NET est m'arrête, pourquoi ne pas me prévenir plus tôt, quand j'ai appelé Demand()?

J'obtiens le résultat suivant:

Suis-je un administrateur? Faux 
Lire l'accès est autorisé: C:\Program Files\Microsoft Office\Office14\BCSLaunch.dll => True 
Écrire le fichier de sauvegarde est autorisée: C:\Program Files\Microsoft Office\Office14\BCSLaunch.bak => True 
Système.UnauthorizedAccessException: le chemin d'Accès " C:\Program Files\Microsoft Office\Office14\BCSLaunch.bak " est refusé. 
au Système.IO.__Erreur.WinIOError(Int32 errorCode, String maybeFullPath) 
au Système.IO.Fichier.InternalCopy(String sourceFileName, Chaîne destFileName, Boolean écraser) 
au Système.IO.Fichier.Copier(String sourceFileName, Chaîne destFileName) 
au TryAndGetUACPrompt.Programme.Main(String[] args) dans C:\Users\.............. 

Svp quelqu'un peut-il m'aider à comprendre pourquoi j'obtiens des informations contradictoires?

--

Mise à jour - 19:30 GMT

J'ai regardé à travers les Acl du fichier source à l'aide du code suivant:

Console.WriteLine("ACL Permissions for Source....");
FileSecurity fileSecurityForOriginalPath = new FileSecurity(path, AccessControlSections.Access);

foreach (FileSystemAccessRule rule in fileSecurityForOriginalPath.GetAccessRules(true,true,typeof(NTAccount)))
{
   Console.WriteLine("{0} => {1}", rule.FileSystemRights, rule.AccessControlType);
}

La sortie est comme suit:

Autorisations ACL pour Source.... 
FullControl => Permettre 
FullControl => Permettre 
ReadAndExecute, Synchroniser => Permettre 

Donc, j'ai accès à la lecture. Cependant, j'ai essayé d'utiliser ce code pour afficher les autorisations du chemin de sauvegarde et de évidemment, j'obtiens une exception que ma sauvegarde (destination) fichier n'existe pas physiquement, donc je ne peux pas vérifier les autorisations sur elle.

Je vais ensuite essayer une autre suggestion pour déplacer cette case à une autre méthode.

Mise à jour - 19:45 GMT

J'ai refait la Lecture/Écriture des demandes en une autre méthode:

private static FileIOPermission CheckWriteAccess(string backupPath)
{
    FileIOPermission writeAccess = new FileIOPermission(FileIOPermissionAccess.AllAccess, backupPath);
    writeAccess.Demand();
    return writeAccess;
}

private static FileIOPermission CheckReadAccess(string path)
{
    FileIOPermission ioPerm = new FileIOPermission(FileIOPermissionAccess.Read, path);
    ioPerm.Demand();
    return ioPerm;
}

Ces deux retour des beaux sans exception.

Par conséquent, si l' .FILET de Sécurité augmente la Dacl, je me demande pourquoi il pense qu'elle sera couronnée de succès, si en réalité il ne l'est pas.

--

Mise à jour 19:57 GMT

Ok, j'ai vérifié les permissions du Répertoire, pas le backupFile (fichier de destination) et a obtenu ce que la sortie (à l'aide d'un foreach sur le AuthorizationRuleCollection .GetAccessRules())

Vérification de l'accès en écriture dans ce répertoire.... 
FullControl => Permettre 
268435456 => Permettre 
FullControl => Permettre 
268435456 => Permettre 
FullControl => Permettre 
268435456 => Permettre 
ReadAndExecute, Synchroniser => Permettre 
-1610612736 => Permettre 
268435456 => Permettre 

J'ai utilisé un Enum.Format(typeof(FileSystemAccessRights),rule,"G") pour obtenir la mise en forme, en fait le ToString(), mais je n'étais pas sûr, ces chiffres étaient corrects.

Code à la sortie de la ci-dessus:

private static DirectorySecurity CheckWriteAccess(string backupPath)
{
    DirectorySecurity writeAccess = new DirectorySecurity( Path.GetDirectoryName(backupPath),AccessControlSections.Access);

    Console.WriteLine("Checking write access in this directory....");
    foreach (FileSystemAccessRule rule in writeAccess.GetAccessRules(true, true, typeof(NTAccount)))
    {
        Console.WriteLine("{0} => {1}", Enum.Format(typeof(FileSystemRights),rule.FileSystemRights,"G"), rule.AccessControlType);
    }

    return writeAccess;
}
Ce n'est pas la .NET runtime qui empêche l'accès, mais le système de fichiers.
Vous êtes juste énumérer les règles de contrôle d'accès (entrée/ACE) dans le fichier/dossier ACL (liste de contrôle d'accès), mais vous êtes en négligeant de les voir utilisateur qui droit. Par exemple, vous affichez "permettre à, permettre à", etc, mais vous n'êtes pas montrer qui est autorisé. Chaque ACE dans une ACL décrit une entité (utilisateur ou groupe) et de leurs droits (r/w/x, etc). Vous n'avez toujours pas démontré que l'utilisateur qui exécute le programme (vous?) a un AS avec fullcontrol sur la ressource que vous tentez d'accéder.
qui est la solution finale, avec des exemples de code source ?
La solution, c'est que mon problème réside dans la sécurité de Windows, pas dans .NET. .NET a été accordée l'autorisation de le fichier (qui n'est pas nié par declaritive de sécurité), mais Windows ne l'était pas. J'espère que ça aide.

OriginalL'auteur Dominic Zukiewicz | 2010-01-27