Najlepszy sposób na uzyskanie ścieżki folderu aplikacji


514

Widzę, że istnieją pewne sposoby uzyskania ścieżki folderu aplikacji:

  1. Application.StartupPath
  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)
  3. AppDomain.CurrentDomain.BaseDirectory
  4. System.IO.Directory.GetCurrentDirectory()
  5. Environment.CurrentDirectory
  6. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)
  7. System.IO.Path.GetDirectory(Application.ExecutablePath)

Jaki jest najlepszy sposób w zależności od sytuacji?


9
Dlaczego mamy wiele sposobów na uzyskanie ścieżki aplikacji. Myślę, że istnieje powód dla każdej drogi.
Leo Vo

1
Wystąpił błąd w # 6: powinien brzmieć: System.Reflection.Assembly.GetExecutingAssembly (). GetName (). CodeBase), System.IO.Path.GetDirectoryName (Application.ExecutablePath)
BillW

2
Brawo dla # 6, gdy jestem w projekcie internetowym, nie chciałem logiki Server.MapPath w mojej bibliotece załadowanej IoC, która nie ma charakteru specyficznego dla sieci
bkwdesign

Mamy teraz niezawodną IHostEnvironment.ContentRootPath, dostępną poprzez wstrzykiwaną IHostEnvironmentzależność (która zawiera inne przydatne rzeczy).
Timo,

Odpowiedzi:


518

AppDomain.CurrentDomain.BaseDirectory jest prawdopodobnie najbardziej przydatny do uzyskiwania dostępu do plików, których lokalizacja jest względna w stosunku do katalogu instalacyjnego aplikacji.

W aplikacji ASP.NET będzie to katalog główny aplikacji, a nie podfolder bin - co jest prawdopodobnie tym, czego zwykle chcesz. W aplikacji klienckiej będzie to katalog zawierający główny plik wykonywalny.

W aplikacji VSTO 2005 będzie to katalog zawierający zestawy zarządzane VSTO dla twojej aplikacji, a nie, powiedzmy, ścieżka do pliku wykonywalnego Excel.

Inne mogą zwracać różne katalogi w zależności od środowiska - na przykład patrz odpowiedź @ Vimvq1987.

CodeBaseto miejsce, w którym plik został znaleziony i może być adresem URL rozpoczynającym się od http: //. W takim przypadku Locationprawdopodobnie będzie pamięć podręczna pobierania zestawu. Nie można zagwarantować, że CodeBase zostanie ustawiony dla zestawów w GAC .


2
Podczas testowania w systemie Windows XP w wersji 32-bitowej zwraca miejsce rozpoczęcia skrótu.
Joshua Son,

1
+1 @Joe i Dodatek na poziomie dokumentu VSTO, patrz TO

3
Pamiętaj, że to zwraca ścieżkę z odwrotnym ukośnikiem na końcu. Powodowało to problemy podczas formatowania łańcucha z wynikiem przekazywanym jako argument procesu.
jeszcze

19
@avenmore - Jeśli formatujesz ciąg w celu zbudowania ścieżki, rozważ użycie Path.Combinezamiast niego. To zajmie się końcowym ukośnikiem odwrotnym.
Joe

1
To zwraca mi folder bin / debugowania w VS 2017, a nie katalog główny.
SmoveBB

86
  1. Application.StartupPathi 7. System.IO.Path.GetDirectoryName(Application.ExecutablePath)- Działa tylko w przypadku aplikacji Windows Forms

  2. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().Location)

    Daje ci coś takiego: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\42aaba80\\bcf9fd83_4b63d101"gdzie jest strona, którą prowadzisz.

  3. AppDomain.CurrentDomain.BaseDirectorydla aplikacji internetowej może być przydatna i zwróci coś takiego, "C:\\hg\\Services\\Services\\Services.Website\\"który jest katalogiem podstawowym i jest całkiem przydatny.

  4. System.IO.Directory.GetCurrentDirectory() i 5. Environment.CurrentDirectory

poda lokalizację, z której został uruchomiony proces - więc dla aplikacji sieci Web działającej w trybie debugowania z Visual Studio coś takiego "C:\\Program Files (x86)\\IIS Express"

  1. System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase)

dostanie lokalizację, w której .dlldziała kod, dla aplikacji internetowej, która może być"file:\\C:\\hg\\Services\\Services\\Services.Website\\bin"

Teraz w przypadku np. Aplikacji konsolowej punktami 2-6 będzie katalog, w którym .exe znajduje się plik.

Mam nadzieję, że to pozwoli Ci zaoszczędzić trochę czasu.


2
Całkiem pewne, że chcieć „bieżącego folderu” dotyczy tylko aplikacji innych niż internetowe ...
Nyerguds

2
Oto odpowiedź.
P.Brian.Mackey,

59

Pamiętaj, że nie wszystkie z tych metod zwrócą tę samą wartość. W niektórych przypadkach mogą zwrócić tę samą wartość, ale bądź ostrożny, ich cele są różne:

Application.StartupPath

zwraca StartupPathparametr (można ustawić podczas uruchamiania aplikacji)

System.IO.Directory.GetCurrentDirectory()

zwraca bieżący katalog, który może, ale nie musi być folderem, w którym znajduje się aplikacja. To samo dotyczy Environment.CurrentDirectory. Jeśli używasz tego w pliku DLL, zwróci ścieżkę do miejsca, w którym proces jest uruchomiony (jest to szczególnie prawdziwe w ASP.NET).


7
Proszę, proszę, nie używaj GetCurrentDirectory(), dla miłości biegania z różnych ścieżek! :(
kayleeFrye_onDeck

@kayleeFrye_onDeck nie podałeś powodów poprzedniego pytania.
chyba

10

W przypadku aplikacji internetowej, aby uzyskać bieżący katalog główny aplikacji sieciowej, zazwyczaj wywołuj stronę WWW dla bieżącego przychodzącego żądania:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Powyższy opis kodu


6

Proces rozpocząłem od usługi systemu Windows za pośrednictwem interfejsu Win32 API w sesji od użytkownika, który jest faktycznie zalogowany (w sesji Menedżera zadań 1 nie 0). W ten sposób możemy dowiedzieć się, która zmienna jest najlepsza.

Dla wszystkich 7 przypadków z powyższego pytania wyniki są następujące:

Path1: C:\Program Files (x86)\MyProgram
Path2: C:\Program Files (x86)\MyProgram
Path3: C:\Program Files (x86)\MyProgram\
Path4: C:\Windows\system32
Path5: C:\Windows\system32
Path6: file:\C:\Program Files (x86)\MyProgram
Path7: C:\Program Files (x86)\MyProgram

Być może jest to pomocne dla niektórych z was, robiąc te same rzeczy, gdy szukacie najlepszej zmiennej dla swojego przypadku.


4
Bardzo trafna odpowiedź. Tak wiele osób zapomina o tym „katalogu roboczym”! = „Katalog programu”.
Nyerguds

3

Z mojego doświadczenia wynika, że ​​najlepszym sposobem jest połączenie ich.

  1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase Otrzymasz folder bin
  2. Directory.GetCurrentDirectory() Działa dobrze na .Net Core, ale nie .Net i daje katalog główny projektu
  3. System.AppContext.BaseDirectoryi AppDomain.CurrentDomain.BaseDirectory Działa dobrze w .Net, ale nie w .Net core i daje katalog główny projektu

W bibliotece klas, która ma być target.Net i .Net core, sprawdzam, który szkielet obsługuje bibliotekę i wybieram jedną lub drugą.


2

Użyłem tego z powodzeniem

System.IO.Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName)

Działa nawet wewnątrz Linqpada.


1
brakuje w nim nawiasu otwierającego GetCurrentProcess. btw ocenia na C: \ Program Files \ dotnet w moim podstawowym projekcie .net podczas debugowania w Visual Studio, ponieważ tam właśnie znajduje się
dotnet.exe

1

Katalog główny:

DriveInfo cDrive = new DriveInfo(System.Environment.CurrentDirectory);
var driverPath = cDrive.RootDirectory;

1
Wygląda na to, że pobiera bieżący katalog roboczy, chociaż może to czasem być przydatne, ale zdecydowanie nie jest to ścieżka do pliku EXE.
krowe2

0

Jeśli wiesz, jak uzyskać katalog główny:

string rootPath = Path.GetPathRoot(Application.StartupPath)

0

ten System.IO.Path.GetDirectory(Application.ExecutablePath)zmienił się naSystem.IO.Path.GetDirectoryName(Application.ExecutablePath)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.