Laden...
FAQ

[FAQ] Pfad zur eigenen Anwendung (EXE) ermitteln

Erstellt von herbivore vor 15 Jahren Letzter Beitrag vor 8 Jahren 92.405 Views
herbivore Themenstarter:in
49.485 Beiträge seit 2005
vor 15 Jahren
[FAQ] Pfad zur eigenen Anwendung (EXE) ermitteln

Hallo Community,

um das Verzeichnis zu ermitteln, in dem sich die EXE-Datei der eigenen Anwendung befindet, bietet es sich in Windows Forms-Anwendungen an

Application.StartupPath

zu verwenden. Wenn man eine WPF- oder Konsolenanwendung hat, kann man trotzdem StartupPath verwenden, aber man muss dann i.d.R. den Verweis auf System.Windows.Forms.dll noch selbst hinzufügen und man muss den Klassennamen vollqualifiziert angeben, also System.Windows.Forms.Application.StartupPath. Es gibt jedoch Anwendungstypen (z.B. Dienste), bei denen Application.StartupPath kein oder ein falsches Ergebnis liefert.

Hat man so einen Anwendungstyp oder möchte man einfach die Abhängigkeit zu Windows.Forms nicht haben, kann man stattdessen

Path.GetDirectoryName (Assembly.GetEntryAssembly ().Location);

verwenden. Leider liefert Assembly.Get**Entry**Assembly in bestimmten Fällen das falsche Ergebnis (null), z.B. wenn man im Visual Studio eine NUnit test.dll mit dem NUnit-Gui startet. Kann das vorkommen, kann man

Path.GetDirectoryName (Assembly.GetExecutingAssembly ().Location);

verwenden (also mit Assembly.Get**Executing**Assembly). Dieser Code muss dann jedoch unbedingt im Code der EXE selbst stehen. Er darf dann nicht in einer DLL stehen, zumindest nicht, wenn die DLL in einem anderen Verzeichnis liegt. Es würde dann das Verzeichnis der DLL ermittelt werden.

Um den Pfad der aktuellen aspx-Datei auf dem Server zu ermitteln, muss man die Eigenschaft Page.Request/HttpRequest.PhysicalPath benutzen.

Compact Framework: Im CF gibt es weder Application.StartupPath noch die Assembly.Location Eigenschaft. Für erstere gibt es die schon genannten Alternativen, für letztere gibt es Assembly.GetName ().CodeBase als Ersatz.

Achtung: Das aktuelle Arbeitsverzeichnis

Environment.CurrentDirectory

wird aus historischen und Bequemlichkeitsgründen in vielen Fällen mit dem Verzeichnis der EXE übereinstimmen; aber darauf sollte man sich besser nicht verlassen! Eigentlich ist Arbeitsverzeichnis sowieso dafür gedacht, auf das Verzeichnis zu zeigen, in dem die Dokumente liegen, die vom Programm angezeigt oder mit ihm bearbeitet werden sollen. Das ist der eigentliche Zweck von Environment.CurrentDirectory.

Achtung: Aus dem Verzeichnis der EXE sollte nur gelesen, aber nicht dorthin geschrieben werden. Seit Windows Vista sind die Standardeinstellungen ohnehin so, dass ein Schreiben in Programmverzeichnise nicht möglich ist. Welches Verzeichnis stattdessen zum Schreiben verwendet werden sollte, hängt von der Art der Daten (temporäre Dateien, Konfigurationsdaten, Anwendungsdaten, Benutzerdaten ...) ab. Es würde den Rahmen sprengen, das hier im Detail zu besprechen. Interessant ist aber sicher ein Blick auf die Environment.SpecialFolder-Enumeration.

Hinweis: Wenn man den vollständigen Pfad zu einer Datei im Verzeichnis der EXE oder einem Unterverzeichnis davon zusammenbauen möchte, sollte man das nicht mit String-Operationen tun, sondern unbedingt mit Path.Combine. Überhaupt sollte man sich angewöhnen, alle Arbeiten an Pfaden mit den Methoden der Path-Klasse durchführen.

Achtung: Bei Application.ExecutablePath (nicht zu verwechseln mit Application.StartupPath) gibt es anscheinend Probleme, wenn ein Doppelkreuz im Pfad vorhanden ist, siehe Application.ExecutablePath und Effekte durch Sonderzeichen im Path.

herbivore

6.910 Beiträge seit 2009
vor 10 Jahren

Hallo Community,

Ergänzung

neben den oben erwähnten Möglichkeiten, um den Pfad zur eigenen Anwendung zu ermitteln, gibt es eine weitere Möglichkeit:


AppDomain.CurrentDomain.BaseDirectory

Damit diese Möglichkeit das erwartete Ergebnis liefert, muss AppDomainSetup (siehe AppDomains) unverändert auf den Standardeinstellungen bleiben, was jedoch für "normale" Desktop- und Web-Anwendungen sowie für Dienste der Fall ist. Die Einschränkungen von Assembly.Get**Entry**Assembly und Assembly.Get**Executing**Assembly existieren bei AppDomain.CurrentDomain.BaseDirectory nicht.

Verwendet die Anwendung ShadowCopying, ist die Frage, was unter "Pfad zur EXE" verstanden wird. Ist es der Pfad, an dem die EXE ursprünglich liegt, oder der Pfad im ShadowCopy-Verzeichnis, an dem die EXE tatsächlich ausgeführt wird? AppDomain.CurrentDomain.BaseDirectory liefert ersteren Pfad.

Werden mehrere Anwendungs-Domänen verwendet, so kann der Pfad, unter den genannten Einschränkungen, auf die gleiche Weise ermittelt werden. Bei domänenübergreifendem Aufruf ist zusätzlich zu beachten, dass CurrentDomain die Anwendungs-Domäne des aktuellen Ausführungs-Threads zurück gibt.

Das korrekte Verhalten sollte aber, auch wie bei den anderen Methoden, unbedingt durch Tests überprüft werden.

Fazit

Als Empfehlung kann bei WinForms Application.StartupPath und bei allen anderen Projekttypen AppDomain.CurrentDomain.BaseDirectory verwendet werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

16.792 Beiträge seit 2008
vor 8 Jahren

Bei ASP.NET Core funktioniert das ein wenig anders; hier gibt es die Möglichkeit den Start-Pfad direkt über IWebHostenvironment (bis .NET 5)bzw. IHostEnvironment (ab .NET Core 3) zu erhalten

Die Eigenschaft dazu ist: ContentRootPath


2021-08-20: Aktualisierung auf IHostEnvironment