c # - UnauthorizedAccessException 'Adgang til stien er nægtet' fra File.ReadAllBytes i LOCALAPPDATA

Indlæg af Hanne Mølgaard Plasc

Problem



Denne undtagelse forekommer intermitterende for den samme bruger for den samme maskine, når man læser filer inden for \%LOCALAPPDATA\%.


Forskning


Jeg har tjekket alle mulige dubletter, der i øjeblikket tilbydes af denne titel (der er meget). Der er en, der vedrører læsning af en AES-krypteret fil, som ikke har noget svar; og jeg tror ikke, da disse filer ikke er krypterede.


De fleste af dem har at gøre med at skrive filer (men jeg læser en fil), eller er de indlysende årsager som dokumenteret på MSDN for File.ReadAllBytes (string). [12]


De tre forklaringer til denne undtagelse er der:



  1. 'Denne operation understøttes ikke på den nuværende platform' - Jeg ved ikke hvad det betyder, men da dette virker til tider for den samme bruger på samme maskine (jeg vil forklare nedenfor), tror jeg jeg kan udelukke dette.

  2. ' vej angav en mappe' - som du vil se fra koden nedenfor, bliver opkaldet foretaget inden for en check på File.Exists, så jeg tror jeg kan udelukke dette.

  3. 'Den, der ringer op, har ikke den nødvendige tilladelse.' Dette er den sædvanlige forklaring på denne undtagelse, og jeg formoder, at jeg får en slags 'frynse tilfælde' af dette.



Scenarie


Dette sker, når en applikation, der kører som en domænebruger, læser en fil i en undermappe på \%LOCALAPPDATA\% af den samme bruger (for hvilken der ikke bør være tilladelsesproblemer for den pågældende bruger at læse filer). Undermapperne i det følger bare den normale 'CompanyName' \ 'ApplicationName' -struktur, og der er ingen yderligere tilladelser anvendt på undermapperne (vi bruger bare mappen til at holde vores filer væk fra andre personer).


Undtagelse



  System.UnauthorizedAccessException: Adgang til stien ' [[redacted]] ' er
  nægtet. på System.IO .\_\_ Error.WinIOError (Int32 errorCode, String
  maybeFullPath) på System.IO.FileStream.Init (String path, FileMode
  tilstand, FileAccess adgang, Int32 rettigheder, Boolean useRights, FileShare
  del, Int32 bufferSize, FileOptions indstillinger, SECURITY\_ATTRIBUTES
  secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath,
  Boolean checkHost) på System.IO.FileStream..ctor (String path,
  FileMode-tilstand, FileAccess-adgang, FileShare-deling, Int32 bufferSize,
  FileOptions muligheder, String msgPath, Boolean bFromProxy, Boolean
  useLongPath, Boolean checkHost) på
  System.IO.File.InternalReadAllBytes (Strengevej, Boolean checkHost)

  ved koden nedenfor



Kode


        // Note that filename is within \%LOCALAPPDATA\%
        if (File.Exists(fileName))
        {
            var readAllBytes = File.ReadAllBytes(fileName); // exception here
            // etc...
        }


Bevis for, at det er intermittent


Og jeg kan bevise fra kombinationen af ​​vores fejllogfiler og andre oplysninger om, at dette virker mest af tiden, og jeg kan bevise følgende begivenhedssekvens for en bestemt kombination af maskine og bruger:



  • Programmet virker derefter

  • Denne undtagelse opstår (måske flere gange, med forsinkelser forsynet eksponentielt forøges hver gang: 1minute, 2minutter, 4minutter osv.), så

  • Programmet virker igen



Jeg tror ikke på, at der er sket nogen væsentlig ændring (f.eks. Tilladelser) til filsystemet for at rette op på det. Jeg undrer mig over, om det kan skyldes et problem med fringe tilladelser, for eksempel hvis deres adgangskode er ved at udløber eller er for nylig blevet ændret.


Jeg har et bestemt eksempel, da jeg bemærkede denne fejl opstod, og jeg råde brugeren til at genstarte deres maskine, og problemet gik væk.


Spørgsmål


Kan nogen give mig en autoritativ forklaring på årsagen til dette, over hvad jeg allerede har gættet, eller for at bekræfte, hvad det er?

Bedste reference


Spørgsmålet er for bredt, men jeg vil gerne påpege, at der er andre grunde til at få adgang til at nægte undtagelse foruden din liste. Overvej f.eks. Dette enkle program:


public class Program {
    static string \_target = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "test", "test.txt");
    static void Main(string[] args) {
        File.Create(\_target).Dispose();
        ProcessFile();

        // below throws access denied
        if (File.Exists(\_target))
            Console.WriteLine(File.ReadAllText(\_target));
        Console.ReadKey();
    }

    static void ProcessFile() {
        // open and abandon handle
        var fs = new FileStream(\_target, FileMode.Open, FileAccess.Read, FileShare.Delete);
        // delete
        File.Delete(\_target);
    }        
}  


Her opretter vi en ny fil under \%LOCALAPPDATA\%, og åbner den med FileShare.Delete, men ikke lukker. FileShare.Delete tillader efterfølgende sletning af filen, men filen vil ikke blive slettet, før alle håndtag til den er lukket.


Så fortsætter vi med File.Delete, som slet ikke sletter filen, men markerer den for sletning, fordi vi stadig har åbent filhåndtag til det.


Nu, File.Exists returnerer sandt for en sådan fil, men forsøger at få adgang til det smider 'Access nægtet' undtagelse som beskrevet.


Hvorvidt denne specifikke situation er relevant for din sag, er svært at vide, men det kan være.


Mit punkt er hovedsagelig: Du bør forvente sådanne undtagelser (og også 'fil allerede i brug' slags undtagelser) og håndtere dem ved at prøve igen. De kan ske af forskellige årsager uden for din kontrol.