Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
[FAQ] Pfad zur eigenen Anwendung (EXE) ermitteln
herbivore
myCSharp.de - Experte

Avatar #avatar-2627.gif


Dabei seit:
Beiträge: 52329
Herkunft: Berlin

Themenstarter:

[FAQ] Pfad zur eigenen Anwendung (EXE) ermitteln

beantworten | zitieren | melden

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.GetEntryAssembly 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.GetExecutingAssembly). 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
private Nachricht | Beiträge des Benutzers
gfoidl
myCSharp.de - Team

Avatar #avatar-2894.jpg


Dabei seit:
Beiträge: 7541
Herkunft: Waidring

beantworten | zitieren | melden

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.GetEntryAssembly und Assembly.GetExecutingAssembly 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!"
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15827
Herkunft: BW

beantworten | zitieren | melden

Bei DNX Projekten (ASP.NET Core / .NET Core) funktioniert das ganze aufgrund der völlig neuen Umgebung ein wenig anders.

Dazu gibt es zwei verschiedene Lösungen:

1) Microsoft.Extensions.PlatformAbstractions
Hinzufügen der Dependency Microsoft.Extensions.PlatformAbstractions.
Danach kann man folgendes verwenden

string appDirectory = PlatformServices.Default.Application.ApplicationBasePath
PlatformServices.Default.Application ist dabei vom Typ IApplicationEnvironment.

Diese ist vor allem bei Web-Anwendungen empfohlen.
ASP.NET Anwendungen selbst haben direkt auch die Möglichkeit

IApplicationEnvironment.ApplicationBasePath
zu verwenden, der ja beim Start der Anwendung injeziert wird.

2) System.AppContext

string appDirectory = System.AppContext.BaseDirectory
Dies ist bei allen DNX Projekten ohne weitere Dependency möglich.
private Nachricht | Beiträge des Benutzers