Найкращий спосіб отримати шлях до папки додатків


514

Я бачу, що є кілька способів отримати шлях до папки додатків:

  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)

Який найкращий спосіб залежно від ситуації?


9
Чому у нас є багато способів отримати шлях до програми. Я думаю, що для кожного способу є причина.
Лев Во

1
У № 6 є помилка: слід прочитати: System.Reflection.Assembly.GetExecutingAssembly (). GetName (). CodeBase), System.IO.Path.GetDirectoryName (Application.ExecutablePath)
BillW

2
Ура для # 6, поки я перебуваю у веб-проекті, я не хотів логіки Server.MapPath в моїй бібліотеці завантажених IoC, яка не є специфічною для веб-сайту
bkwdesign

Зараз ми маємо надійну IHostEnvironment.ContentRootPath, до якої звертаємося через ін'єкційну IHostEnvironmentзалежність (яка містить інші корисні речі).
Тимо

Відповіді:


518

AppDomain.CurrentDomain.BaseDirectory є, мабуть, найбільш корисним для доступу до файлів, розташування яких відносно каталогу встановлення додатків.

У додатку ASP.NET це буде кореневий каталог програми, а не підпапка bin - що, мабуть, те, що ви зазвичай хочете. У клієнтській програмі це буде каталог, що містить основний виконуваний файл.

У застосуванні VSTO 2005 це буде каталог, що містить керовані VSTO збірки для вашої програми, а не, скажімо, шлях до виконуваного файлу Excel.

Інші можуть повертати різні каталоги залежно від вашого оточення - наприклад, див. Відповідь @ Vimvq1987.

CodeBase- це місце, де було знайдено файл, і це може бути URL, що починається з http: //. У цьому випадку Location, ймовірно, буде кеш завантаження збірки. Гарантія CodeBase не встановлюється для зборів у GAC .


2
Під час тестування в Windows XP 32bit він повертається там, де розпочався ярлик.
Джошуа син

1
+1 @Joe та надбудову для документа

3
Майте на увазі, що це повертає шлях із зворотним нахилом в кінці. Це викликало у мене проблеми при форматуванні рядка з результатом, який передається як аргумент процесу.
avenmore

19
@avenmore - Якщо ви форматуєте рядок для побудови шляху, подумайте про використання Path.Combineцього. Це допоможе подбати про зворотний нахил для вас.
Джо

1
Це повернення для мене папки bin / debug у VS 2017, а не кореневого каталогу.
SmoveBB

86
  1. Application.StartupPathта 7. System.IO.Path.GetDirectoryName(Application.ExecutablePath)- Працює лише для програми Windows Forms

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

    Подарує вам щось на кшталт: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\Temporary ASP.NET Files\\legal-services\\e84f415e\\96c98009\\assembly\\dl3\\42aaba80\\bcf9fd83_4b63d101"де знаходиться сторінка, яку ви ведете.

  3. AppDomain.CurrentDomain.BaseDirectoryдля веб-додатків може бути корисним і поверне щось на зразок "C:\\hg\\Services\\Services\\Services.Website\\"базового каталогу та досить корисного.

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

отримає вам місце розташування, з якого процес був звільнений - тому для веб-додатків, що працюють у режимі налагодження від Visual Studio, щось подібне "C:\\Program Files (x86)\\IIS Express"

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

отримає вам місце, де .dllзнаходиться цей код, для веб-програми, яка це може бути"file:\\C:\\hg\\Services\\Services\\Services.Website\\bin"

Тепер у випадку, наприклад, консольного додатка, пункти 2-6 будуть каталогом, де .exe знаходиться файл.

Сподіваюсь, це заощадить певний час.


2
Досить впевнений, що бажання "поточної папки" все одно актуальне лише для не веб-додатків ...
Nyerguds,

2
Це відповідь.
P.Brian.Mackey

59

Зауважте, що не всі ці методи повернуть однакове значення. У деяких випадках вони можуть повернути одне і те ж значення, але будьте обережні, їх цілі різні:

Application.StartupPath

повертає StartupPathпараметр (може бути встановлений під час запуску програми)

System.IO.Directory.GetCurrentDirectory()

повертає поточний каталог, який може бути, а може і не бути папкою, де знаходиться програма. Те ж саме стосується Environment.CurrentDirectory. Якщо ви використовуєте це у файлі DLL, він поверне шлях того, де працює процес (особливо це стосується ASP.NET).


7
Будь ласка, будь ласка, не використовуйте GetCurrentDirectory()для любові керувати речами з різних стежок! :(
kayleeFrye_onDeck

@kayleeFrye_onDeck ви не ставили своїх причин для попереднього питання.
nless

10

Щоб отримати поточний кореневий каталог веб-додатків, щоб отримати поточний кореневий каталог веб-додатків, зазвичай телефонуйте за веб-сторінкою для поточного вхідного запиту:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Вище опис коду


6

Я запустив процес із сервісу Windows через API Win32 у сеансі від користувача, який фактично увійшов (у сесії диспетчера завдань 1, а не 0). У цьому ми могли дізнатися, яка змінна є найкращою.

Для всіх 7 випадків із вищезазначеного питання наведені нижче результати:

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

Можливо, це корисно для деяких із вас, роблячи ті самі речі, коли шукаєте найкращу змінну для вашого випадку.


4
Дуже відповідна відповідь. Так багато людей забувають, що "робочий каталог"! = "Каталог програм".
Nyerguds

3

На мій досвід, найкращим способом є їх поєднання.

  1. System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase Дасть вам папку бін
  2. Directory.GetCurrentDirectory() Відмінно працює на .Net Core, але не .Net і дасть вам кореневий каталог проекту
  3. System.AppContext.BaseDirectoryі AppDomain.CurrentDomain.BaseDirectory прекрасно працює у .Net, але не .Net core та надасть вам кореневу директорію проекту

У бібліотеці класів, яка повинна бути націленою.Net та .Net core, я перевіряю, в якій структурі розміщується бібліотека, і вибираю ту чи іншу.


2

Я успішно користувався цим

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

Він працює навіть всередині linqpad.


1
для цього не вистачає дужки відкриття GetCurrentProcess. btw він оцінює C: \ Program Files \ dotnet в моєму базовому проекті .net під час налагодження у візуальній студії, тому що там знаходиться
dotnet.exe

1

Кореневий каталог:

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

1
Здається, це отримує поточний робочий каталог, хоча це може бути корисно іноді, але це точно не гарантовано, що це шлях EXE.
krowe2


0

цей System.IO.Path.GetDirectory(Application.ExecutablePath)змінився наSystem.IO.Path.GetDirectoryName(Application.ExecutablePath)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.