Uygulama klasörü yolunu almanın en iyi yolu


515

Uygulama klasörü yolunu almanın bazı yolları olduğunu görüyorum:

  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)

Duruma bağlı olarak en iyi yol nedir?


9
Uygulama yolunu almak için neden çok yolumuz var? Bence her yol için bir sebep var.
Leo Vo

1
# 6'da bir hata var: şöyle olmalıdır: System.Reflection.Assembly.GetExecutingAssembly (). GetName (). CodeBase), System.IO.Path.GetDirectoryName (Application.ExecutablePath)
BillW

2
Bir web projesindeyken # 6 için hooray, doğada web'e özgü olmayan IoC yüklü kütüphanemde Server.MapPath mantığı istemiyordum
bkwdesign

Artık güvenilir IHostEnvironment.ContentRootPath, enjekte edilen bir IHostEnvironmentbağımlılıktan erişilen (başka yararlı şeyler içeren) var.
Timo

Yanıtlar:


519

AppDomain.CurrentDomain.BaseDirectory konumu uygulama yükleme dizinine göreceli olan dosyalara erişmek için muhtemelen en kullanışlıdır.

Bir ASP.NET uygulamasında bu, bin alt klasörü değil, uygulama kökü dizini olacaktır - bu genellikle istediğiniz şeydir. Bir istemci uygulamasında, ana yürütülebilir dosyayı içeren dizin olacaktır.

Bir VSTO 2005 uygulamasında, örneğin Excel yürütülebilir dosyasının yolu değil, uygulamanız için VSTO yönetilen derlemelerini içeren dizin olacaktır.

Diğerleri ortamınıza bağlı olarak farklı dizinler döndürebilir - örneğin @ Vimvq1987'nin cevabına bakın.

CodeBasebir dosyanın bulunduğu yerdir ve http: // ile başlayan bir URL olabilir. Bu durumda Locationmuhtemelen montaj indirme önbelleği olacaktır. CodeBase derlemeler için ayarlanmış olması garanti edilmez GAC .


2
Windows XP 32bit'te test ederken, kısayolun başladığı yere geri döner.
Joshua Son

1
+1 @Joe ve VSTO belge düzeyinde eklenti için bkz. BU

3
Bunun sonunda ters eğik çizgi içeren bir yol döndürdüğünü unutmayın. Bu, bir dizeyi biçimlendirirken işlem argümanı olarak geçecek şekilde sorunlara neden oldu.
avenmore

19
@avenmore - Bir dizeyi yol oluşturmak için biçimlendiriyorsanız Path.Combinebunun yerine kullanmayı düşünün . Bu sizin için ters eğik çizgi ile ilgilenecektir.
Joe

1
Bu, kök dizin yerine VS 2017'de bin / debug klasörünü benim için döndürüyor.
SmoveBB

86
  1. Application.StartupPathSystem.IO.Path.GetDirectoryName(Application.ExecutablePath)- 7. Sadece Windows Forms uygulaması için çalışacak

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

    Size şöyle bir şey verecek: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\42aaba80\\bcf9fd83_4b63d101"çalıştırdığınız sayfanın olduğu yer.

  3. AppDomain.CurrentDomain.BaseDirectoryweb uygulaması için yararlı olabilir ve "C:\\hg\\Services\\Services\\Services.Website\\"temel dizin ve oldukça yararlı gibi bir şey dönecektir .

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

işlemin nereden başlatıldığının yerini alır - böylece Visual Studio'dan hata ayıklama modunda çalışan web uygulaması için "C:\\Program Files (x86)\\IIS Express"

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

.dllkodun çalıştığı yere , web uygulaması için"file:\\C:\\hg\\Services\\Services\\Services.Website\\bin"

Örneğin, örneğin, konsol uygulama noktaları 2-6 .exe dosyasının bulunduğu dizin olacaktır .

Umarım bu size biraz zaman kazandırır.


2
"Geçerli klasör" istemek sadece zaten web olmayan uygulamalar için geçerlidir ...
Nyerguds

2
Cevap bu.
P.Brian.Mackey

59

Bu yöntemlerin hepsinin aynı değeri döndürmeyeceğini unutmayın. Bazı durumlarda, aynı değeri döndürebilirler, ancak dikkatli olun, amaçları farklıdır:

Application.StartupPath

StartupPathParametreyi döndürür (uygulamayı çalıştırdığınızda ayarlanabilir)

System.IO.Directory.GetCurrentDirectory()

uygulamanın bulunduğu klasör olabilir veya olmayabilir geçerli dizini döndürür. Aynı şey geçerli Environment.CurrentDirectory. Bunu bir DLL dosyasında kullanıyorsanız, işlemin çalıştığı yolu döndürür (bu özellikle ASP.NET'te doğrudur).


7
Lütfen GetCurrentDirectory()farklı yollardan bir şeyler yürütme sevgisi için lütfen kullanmayın ! :(
kayleeFrye_onDeck

@kayleeFrye_on Önceki soru için nedenlerinizi belirtmediniz.
nless

10

Bir web uygulaması için, geçerli web uygulaması kök dizinini almak için, genellikle gelen istek için web sayfasını arayın:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Kod açıklamasının üstünde


6

Oturum açmış olan kullanıcıdan oturumda Win32 API üzerinden bir Windows Hizmeti'nden bir işlem başlattım (Görev Yöneticisi oturumunda 1 değil 0). Burada hangi değişkenin en iyi olduğunu öğrenebilirdik.

Yukarıdaki sorudaki 7 vakanın tümü için, sonuçlar aşağıdadır:

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

Belki de sizin durumunuz için en iyi değişkeni ararken aynı şeyleri yapmak bazılarınız için yararlıdır.


4
Çok alakalı bir cevap. Pek çok insan "çalışma dizini"! = "Program dizinini" unutuyor.
Nyerguds

3

Deneyimlerime göre, en iyi yol bunların bir kombinasyonudur.

  1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase Size bin klasörünü verecek
  2. Directory.GetCurrentDirectory() .Net Core üzerinde çalışıyor ancak .Net üzerinde çalışmıyor ve size projenin kök dizinini verecek
  3. System.AppContext.BaseDirectoryve AppDomain.CurrentDomain.BaseDirectory .Net çekirdeğinde iyi çalışır ve .Net çekirdeğinde çalışmaz ve size projenin kök dizinini verir

Target.Net ve .Net çekirdeği olması gereken bir sınıf kütüphanesinde hangi çerçevenin kütüphaneyi barındırdığını kontrol edip birini ya da diğerini seçiyorum.


2

Bunu başarıyla kullandım

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

Linqpad'in içinde bile çalışır .


1
GetCurrentProcess açılış köşeli ayraç eksik. btw, .net çekirdek projemdeki C: \ Program Files \ dotnet olarak değerlendirilir, çünkü dotnet.exe'nin bulunduğu yer budur
t0b4cc0

1

Kök dizini:

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

1
Bu, geçerli çalışma dizinini alıyor gibi görünüyor, ancak bazen yararlı olsa da, kesinlikle EXE yolu olduğu garanti edilmez.
krowe2

0

Kök dizini almayı biliyorsanız:

string rootPath = Path.GetPathRoot(Application.StartupPath)

0

bu System.IO.Path.GetDirectory(Application.ExecutablePath)değiştiSystem.IO.Path.GetDirectoryName(Application.ExecutablePath)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.