none
Zugriffsrechte für Verzeichnis oder Datei ermitteln RRS feed

  • Frage

  • Hi,

    ich  eine Verzeichnisstruktur nach bestimmten Dateien durchsuchen. Wie kann ich vermeiden, dass bei fehlend Rechten Exceptions geworfen werden, oder anders gefragt, wie kann ich vor Zugriff abklären, ob mine Rechte ausreichen?

    Beispiel

            private void DoHandleDirectory(DirectoryInfo di)
            {
                try
                {
                    if ((di.Attributes & FileAttributes.Hidden) == FileAttributes.Hidden) return;
                    DoHandleDirectories(di.GetDirectories()); // <- hier werden die Exceptions geworfen
                    DoHandleFiles(di.GetFiles()); // <- hier werden die Exceptions geworfen
                }
                catch (Exception ex)
                {
                    OwnerForm.DoEx("Projectform:DoHandleDirectory: " + "Fehler bei Verzeichnisbehandlung", ex);
                }

            }

    Schon mal danke für die Mithilfe.

     

     

    Mittwoch, 20. April 2011 08:13

Antworten

  • Hallo Werner,

    Dieses Verhalten ist "by design".

    Du mußt die Verzeichnisse manuell durchlaufen und die Ausnahmen abfangen.
    Der Nachteil dabei ist, dass diese Methode viel langsamer ist.

    Gewusst wie: Durchlaufen einer Verzeichnisstruktur (C#-Programmierhandbuch):
    http://msdn.microsoft.com/de-de/library/bb513869.aspx 

    Auch die neue API in .NET 4.0 ([Directory]/[DirectoryInfo].[EnumerateDirectories]/[EnumerateFiles]) zeigt die gleichen Schwächen, aber man hat nun die Möglichkeit, bei der Iteration über das zurückgegebene IEnumerable (wenn man LINQ verwendet) oder beim Durchlaufen der Iterationsschleife, die Ausnahmen abzufangen und mit der Aufzählung der Dateien nach der Datei/Verzeichnis fortzusetzen, welche die Ausnahme verursacht haben.

    Directory.EnumerateDirectories-Methode (String):
    http://msdn.microsoft.com/de-de/library/dd383304.aspx

    Gruß
    Marcel

    Mittwoch, 20. April 2011 10:10
    Moderator
  • Hallo Werner,

    hier sind zunächst Hinweise für mögliche Lösungsansätze:

    [c# - Need to resume Try after Catch block - Stack Overflow]
    http://stackoverflow.com/questions/5290356/need-to-resume-try-after-catch-block

    Eine Verbesserungs-Möglichkeit ist auch die Ausführung mit elevierten Rechten.
    Techniken, dass bestimmte Attribute aus der Suche herausgenommen werden, hast Du ja zum Teil schon drin, aber hier kannst Du auch noch andere Attribute gegenchecken. Insbesondere die ab Vista hinzugekommenen JunctionPoints [Info], die also die DateiAttribute [ReparsePoint, Hidden, und System] werden bei diesen rekrusiven Suchen oft ausgelassen.
    Wichtig ist evtl. auch, dass eine Exception im Debug-Modus das erste Mal etwa 2 Sekunden beansprucht, aber dann nur noch sehr sehr wenig Millisekunden.

    Im Release dann auch bei der ersten Exception so sehr wenig.

     


    ciao Frank
    Mittwoch, 20. April 2011 11:34

Alle Antworten

  • Hallo Werner,

    Dieses Verhalten ist "by design".

    Du mußt die Verzeichnisse manuell durchlaufen und die Ausnahmen abfangen.
    Der Nachteil dabei ist, dass diese Methode viel langsamer ist.

    Gewusst wie: Durchlaufen einer Verzeichnisstruktur (C#-Programmierhandbuch):
    http://msdn.microsoft.com/de-de/library/bb513869.aspx 

    Auch die neue API in .NET 4.0 ([Directory]/[DirectoryInfo].[EnumerateDirectories]/[EnumerateFiles]) zeigt die gleichen Schwächen, aber man hat nun die Möglichkeit, bei der Iteration über das zurückgegebene IEnumerable (wenn man LINQ verwendet) oder beim Durchlaufen der Iterationsschleife, die Ausnahmen abzufangen und mit der Aufzählung der Dateien nach der Datei/Verzeichnis fortzusetzen, welche die Ausnahme verursacht haben.

    Directory.EnumerateDirectories-Methode (String):
    http://msdn.microsoft.com/de-de/library/dd383304.aspx

    Gruß
    Marcel

    Mittwoch, 20. April 2011 10:10
    Moderator
  • Hallo Marcel,

     

    zuerst einmal danke für Deine Antwort, auch wenn sie mich nicht sehr befriedigt.


    Du mußt die Verzeichnisse manuell durchlaufen

    das war mir schon klar, und das mache ich auch.

    und die Ausnahmen abfangen.

    Das ist der Punkt, der mir nicht gefällt, das ist elend langsam und es muss doch auch eine andere Möglichkeit geben, es kann doch nicht sein, das der Windows-Explorer beim Durchsuchen einer Festplatte fortlaufend in Ausnahmen reinläuft, oder? 

    Gruß Werner

    Mittwoch, 20. April 2011 10:45
  • Hallo Werner,
    es kann doch nicht sein, das der Windows-Explorer beim Durchsuchen einer Festplatte fortlaufend in Ausnahmen reinläuft, oder?

    was denkst Du, warum die Windows Suche so dermaßen langsam ist?

    Im Endeffekt ist es aber eigentlich auch egal, ob Du nun eine Exception abfängst oder vorher versuchst, die Zugriffsrechte zu ermitteln. Schneller geht letzteres sicher auch nicht. Zudem kann es gut sein, dass man bspw. auf einen Ordner keine ausreichenden Berechtigungen hat, um die Dateien zu lesen, aber dennoch auf die Unterordner und deren Dateien zugreifen darf. Du müsstest also nicht nur ein einzelnes Recht prüfen, was das Ganze nochmal lansgamer macht.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Mittwoch, 20. April 2011 11:07
    Moderator
  • Hallo Werner,

    > Das ist der Punkt, der mir nicht gefällt, das ist elend langsam und es muss doch auch eine andere Möglichkeit geben, es kann doch nicht sein, das der Windows-Explorer beim Durchsuchen einer Festplatte fortlaufend in Ausnahmen reinläuft, oder? 

    Was soll ich sagen: Ich habe aufgezählt, was mit .NET-Klassen möglich ist. Natürlich steht Dir der Weg frei, die Windows API zu verwenden (FindFirstFile, FindNextFile).*

    Listing the Files in a Directory:
    http://msdn.microsoft.com/en-us/library/aa365200(v=vs.85).aspx 

    Gruß
    Marcel

    (*) Dabei ergeben sich aber möglicherweise u.a. Probleme, wenn die SecurityPermissionAttribute.UnmanagedCode-Berechtigung nicht im Subset von AppDomain.CurrentDomain.PermissionSet enthalten ist.

    (**) Man sollte Dateiberechtigungen genausowenig wie Dateisperren im Voraus ermitteln wollen. Der einzig reale Zeitpunkt zum Ermitteln dieser Sachen ist beim tatsächlichen Zugriff auf die Datei.



    Mittwoch, 20. April 2011 11:11
    Moderator
  • Hallo Werner,

    hier sind zunächst Hinweise für mögliche Lösungsansätze:

    [c# - Need to resume Try after Catch block - Stack Overflow]
    http://stackoverflow.com/questions/5290356/need-to-resume-try-after-catch-block

    Eine Verbesserungs-Möglichkeit ist auch die Ausführung mit elevierten Rechten.
    Techniken, dass bestimmte Attribute aus der Suche herausgenommen werden, hast Du ja zum Teil schon drin, aber hier kannst Du auch noch andere Attribute gegenchecken. Insbesondere die ab Vista hinzugekommenen JunctionPoints [Info], die also die DateiAttribute [ReparsePoint, Hidden, und System] werden bei diesen rekrusiven Suchen oft ausgelassen.
    Wichtig ist evtl. auch, dass eine Exception im Debug-Modus das erste Mal etwa 2 Sekunden beansprucht, aber dann nur noch sehr sehr wenig Millisekunden.

    Im Release dann auch bei der ersten Exception so sehr wenig.

     


    ciao Frank
    Mittwoch, 20. April 2011 11:34
  • Hallo Stefan,

    danke für Deinen Beitrag.

    was denkst Du, warum die Windows Suche so dermaßen langsam ist?

    Ich muss gestehen, dass ich mich zwar immer wieder wundere, aber nie daran gedacht habe,  dass das Exception-Handling Ursache war. ;-)

    Im Endeffekt ist es aber eigentlich auch egal, ob Du nun eine Exception abfängst oder vorher versuchst, die Zugriffsrechte zu ermitteln. Schneller geht letzteres sicher auch nicht.


    Ok, in Vebindung mit dem Hinweis von Frank, dass das Verhalten im Debug-Modus nochmals speziell ausgebremst wird, werde ich das mal so hinnehmen.

    Zudem kann es gut sein, dass man bspw. auf einen Ordner keine ausreichenden Berechtigungen hat, um die Dateien zu lesen, aber dennoch auf die Unterordner und deren Dateien zugreifen darf.


    Daran habe ich jetzt überhaupt noch nicht gedacht, wie komme ich denn an eine Datei in einem Unterordner, wenn ich keine Leserechte im übergeordneten Verzeichnis habe? Kann ich solch eine Struktur denn überhaupt durchsuchen?

    Du müsstest also nicht nur ein einzelnes Recht prüfen, was das Ganze nochmal lansgamer macht.

    Ich bin davon ausgegangen, dass ich natürlich die Zugriffsrechte für jeden Ordner/jede Datei prüfen müsste.


    Gruß

    Werner

    Mittwoch, 20. April 2011 12:03
  • Hallo Marcel,

    Natürlich steht Dir der Weg frei, die Windows API zu verwenden (FindFirstFile, FindNextFile).*


    Ok, wenn es dann etwas bringen würde, würde ich auch diesen Weg gehen, so habe ich ja auch früher mit Visual Objects gearbeitet. Wenn aber unter dem Strich das Gleiche rauskäme, wäre es den Aufwand nicht wert.

    Ich muss mal drüber nachdenken.

    (*) Dabei ergeben sich aber möglicherweise u.a. Probleme, wenn die SecurityPermissionAttribute.UnmanagedCode-Berechtigung nicht im Subset von AppDomain.CurrentDomain.PermissionSet enthalten ist.

    Das verstehe ich im Moment noch nicht, da muss ich mich wohl zuerst mal schlauer machen.

    (**) Man sollte Dateiberechtigungen genausowenig wie Dateisperren im Voraus ermitteln wollen. Der einzig reale Zeitpunkt zum Ermitteln dieser Sachen ist beim tatsächlichen Zugriff auf die Datei.

    Na ja, ich denke halt, im Voraus testen würde manche Exception verhindern, dass es beim tatsächlichen Zugriff dann immer noch zu Konflikten kommen kann, ist mir schon klar.

    Nochmals Danke und Gruß

    Werner

    Mittwoch, 20. April 2011 12:13
  • Hallo Frank,

    da hast Du mir mal wieder reichlich Stoff zum nachdenken gegeben.

    [c# - Need to resume Try after Catch block - Stack Overflow]
    http://stackoverflow.com/questions/5290356/need-to-resume-try-after-catch-block

    Dieser Link behandelt exakt meine Ptoblematik, danke.

    Eine Verbesserungs-Möglichkeit ist auch die Ausführung mit elevierten Rechten.

    Diesen Weg möchte ich nicht gehen, denn meine Programme richten sich in der Regel an einen normalen Nutzer und da scheinen mir erweiterte Rechte nicht der richtige Weg zu sein.  

    Techniken, dass bestimmte Attribute aus der Suche herausgenommen werden, hast Du ja zum Teil schon drin, aber hier kannst Du auch noch andere Attribute gegenchecken. Insbesondere die ab Vista hinzugekommenen JunctionPoints [Info], die also die DateiAttribute [ReparsePoint, Hidden, und System] werden bei diesen rekrusiven Suchen oft ausgelassen.

    Ja, vielleicht sollte ich ich auch noch Ausschlusslisten füheren, die eventuell vom Nutzer gepflegt werden können. Ich muss da mal noch drüber nachdenken.

    Wichtig ist evtl. auch, dass eine Exception im Debug-Modus das erste Mal etwa 2 Sekunden beansprucht, aber dann nur noch sehr sehr wenig Millisekunden.

    Im Release dann auch bei der ersten Exception so sehr wenig.

    Das ist ein guter Hinweis, vielleicht habe ich die ganze Sache ja überbewertet.

    Aber zwei Fragen stellen sich mir da noch gerade:

    Wie muss man den Fall behandeln, wenn im Explorer alle Dateien anzeigen eingestellt ist und wie kommt man an die Info? 

    Welches Attribut wird durch das Schloss-Symbol im Explorer dargestellt.?

     

    Danke und Gruß

    Werner

     


    Mittwoch, 20. April 2011 12:26
  • Hallo Werner,

    • Aber zwei Fragen stellen sich mir da noch gerade:
      Wie muss man den Fall behandeln, wenn im Explorer alle Dateien anzeigen eingestellt ist und wie kommt man an die Info?
      Welches Attribut wird durch das Schloss-Symbol im Explorer dargestellt.?

    Also, wenn Du Shell-Erweiterungen erstellen willst, ist folgendes ein guter Einstiegspunkt:

    [Windows® API Code Pack for Microsoft® .NET Framework - Home]
    http://archive.msdn.microsoft.com/WindowsAPICodePack

     

    zu den Schloss-Symbole siehe "padlock icon" ... etwa:

    [Change the permissions and take ownership of your files and folders | Windows Vista, XP and Windows 7 Tutorials]
    http://www.vista4beginners.com/Change-permissions-take-ownership
    [How do I remove padlock icon from all my files?
    ]


    ciao Frank

    Mittwoch, 20. April 2011 13:29
  • Hallo Frank,

    Also, wenn Du Shell-Erweiterungen erstellen willst

    Nein, das will ich nicht, aber ich denke, dass ein Anwender erwartet, das die Einstellungen vom Explorer für Anwendungen übernommen werden, weil diese Einstellungen ja auch für die Filedialoge gelten.

    zu den Schloss-Symbole siehe "padlock icon" ... etwa:

    [Change the permissions and take ownership of your files and folders | Windows Vista, XP and Windows 7 Tutorials]
    http://www.vista4beginners.com/Change-permissions-take-ownership
    [How do I remove padlock icon from all my files?
    ]

    Aber da habe ich nichts gefunden, wie man diesen Zustand per Programm abfragt. Aber ich werde weitersuchen.

    Danke, Gruß und schönen Tag noch

    Werner

    Mittwoch, 20. April 2011 14:41
  • Hallo Werner,

    • Aber da habe ich nichts gefunden, wie man diesen Zustand per Programm abfragt.

    das könntest Du abfragen, aber das Problem wäre ja, dass ggf. die Abfrage der Rechte (des Verzeichnisses für den ausführenden User) wiederum gar nicht erlaubt sein "kann" .. ;-)

    ein Beispiel:

     string verzeichnis = @"c:\Programme";
     var fs = Directory.GetAccessControl(verzeichnis); 
     var sid = fs.GetOwner(typeof(SecurityIdentifier)); 
     bool ok = (sid == new SecurityIdentifier(WellKnownSidType.LocalSystemSid,null));
    

    ggf. Möglichkeiten über Impersonifikation o.ä., also einem Abfrage-User, der z.B. beim Setup angegeben und authentifiziert werden müsste ... etc.


    ciao Frank

    Mittwoch, 20. April 2011 15:01
  • Hallo Werner,

    > Ok, wenn es dann etwas bringen würde, würde ich auch diesen Weg gehen [...]

    Zumindest würdest Du den Preis für die .NET exceptions nicht bezahlen.
    Dafür ist eine robuste Implementation ungleich schwieriger.

    Einen schönen Gruß
    Marcel

    Mittwoch, 20. April 2011 16:43
    Moderator
  • Hallo Werner,

    ist die Frage damit für Dich beantwortet?

     


    ciao Frank
    Donnerstag, 21. April 2011 10:03
  • Hallo Frank,

    entschuldige, dass ich mich noch nicht wieder gemeldet habe, das Thema Abfrage der Rechte musste ich aus Zeitgründen etwas nach hinten schieben.

    Ich melde mich, sobald ich mich damit beschäftigen konnte.

     

    Danke und Gruß

    Werner

     

    Montag, 25. April 2011 07:38