Лучший способ получить путь к папке приложения


515

Я вижу, что есть несколько способов получить путь к папке приложения:

  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,

1
Теперь у нас есть надежная информация IHostEnvironment.ContentRootPath, доступ к которой осуществляется через введенную IHostEnvironmentзависимость (которая содержит другие полезные вещи).
Тимо

Ответы:


519

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

В приложении ASP.NET это будет корневой каталог приложения, а не подпапка bin - что, вероятно, то, что вы обычно хотите. В клиентском приложении это будет каталог, содержащий основной исполняемый файл.

В приложении VSTO 2005 это будет каталог, содержащий управляемые сборки VSTO для вашего приложения, а не, скажем, путь к исполняемому файлу Excel.

Другие могут возвращать разные каталоги в зависимости от вашей среды - например, смотрите ответ @ Vimvq1987.

CodeBaseэто место, где был найден файл, и может быть URL, начинающимся с http: //. В этом случае Location, вероятно, будет сборка кеша загрузки. CodeBase не гарантируется для сборок в GAC .


2
При тестировании в Windows XP 32bit возвращается, где был запущен ярлык.
Иисус Навин

1
+1 @Joe и для надстройки уровня документа VSTO см. ЭТО

3
Имейте в виду, что это возвращает путь с обратной косой чертой в конце. Это вызвало у меня проблемы при форматировании строки с результатом для передачи в качестве аргумента процесса.
Авенмор

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 вы не указали причины предыдущего вопроса.
кроме

10

Для веб-приложения, чтобы получить текущий корневой каталог веб-приложения, обычно звонят по веб-странице для текущего входящего запроса:

HttpContext.Current.Server.MapPath();

System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath;

Выше описания кода


6

Я запустил процесс из службы Windows через Win32 API в сеансе от пользователя, который фактически вошел в систему (в сеансе диспетчера задач 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
Очень актуальный ответ. Так много людей забывают, что «рабочий каталог»! = «Программный каталог».
Ниргудс

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, я проверяю, какая инфраструктура содержит библиотеку, и выбираю одну или другую.


2

Я успешно использовал этот

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

Это работает даже внутри linqpad.


1
в нем отсутствует открывающая скобка GetCurrentProcess. Кстати, он оценивает C: \ Program Files \ dotnet в моем проекте ядра .net при отладке в Visual Studio, потому что именно там находится
dotnet.exe

1

Корневая директория:

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

1
Это похоже на получение текущего рабочего каталога, хотя иногда это может быть полезно, но точно не обязательно указывать путь EXE.
krowe2


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.