Получить путь к приложению


79

Недавно я искал, как получить каталог приложения на Java. Я наконец нашел ответ, но мне потребовалось на удивление много времени, потому что найти такой общий термин непросто. Я думаю, было бы неплохо составить список того, как этого добиться на нескольких языках.

Не стесняйтесь голосовать за / против, если вам (не) нравится идея, и, пожалуйста, внесите свой вклад, если она вам нравится.

Разъяснение:

Существует тонкое различие между каталогом, содержащим исполняемый файл, и текущим рабочим каталогом (указанным pwdв Unix). Первоначально меня интересовало первое, но не стесняйтесь публиковать методы для определения второго (уточняя, какой из них вы имеете в виду).


3
Какой путь вы имеете в виду? Текущий рабочий каталог или каталог, в котором находится исполняемый код?
Поль де Вриз,

Ответы:


59

В Java звонки

System.getProperty("user.dir")

и

new java.io.File(".").getAbsolutePath();

вернуть текущий рабочий каталог.

Призыв к

getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

возвращает путь к JAR-файлу, содержащему текущий класс, или элемент (путь) CLASSPATH, который дал текущий класс, если вы работаете непосредственно из файловой системы.

Пример:

  1. Ваше приложение находится по адресу

     C:\MyJar.jar
    
  2. Откройте оболочку (cmd.exe) и cdперейдите в подкаталог C: \ test \.

  3. Запустите приложение с помощью команды java -jar C:\MyJar.jar.

  4. Первые два вызова возвращают 'C: \ test \ subdirectory'; третий вызов возвращает C: \ MyJar.jar.

При запуске из файловой системы, а не из файла JAR, результатом будет путь к корню созданных файлов классов, например

c:\eclipse\workspaces\YourProject\bin\

Путь не включает каталоги пакетов для созданных файлов классов.

Полный пример получения каталога приложения без имени файла .jar или соответствующего пути к файлам классов при запуске непосредственно из файловой системы (например, при отладке):

String applicationDir = getClass().getProtectionDomain().getCodeSource().getLocation().getPath(); 

if (applicationDir.endsWith(".jar"))
{
    applicationDir = new File(applicationDir).getParent();
}
// else we already have the correct answer

Искал способ поместить файлы только для чтения в тот же пакет, что и классы java ... getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (). GetPath () отлично работал, спасибо!
Нечеткий анализ

@fuzzyanalysis Это именно то Class.getResource(), для чего.
user207421

22

В .NET (C #, VB,…) вы можете запросить текущий Assemblyэкземпляр Location. Однако к нему добавлено имя исполняемого файла. Следующий код очищает путь ( using System.IOи using System.Reflection):

Directory.GetParent(Assembly.GetExecutingAssembly().Location)

В качестве альтернативы вы можете использовать информацию, предоставленную AppDomainдля поиска сборок, на которые имеются ссылки:

System.AppDomain.CurrentDomain.BaseDirectory

VB позволяет использовать другой ярлык через Myпространство имен:

My.Application.Info.DirectoryPath

1
Вы также можете использовать Application.StartupPath для некоторых программ. Однако это не сработает для ASP.NET.
jocull

1
На самом деле это Application.ExecutablePath
zam664

9

В Windows используйте функцию WinAPI GetModuleFileName () . Передайте NULL для дескриптора модуля, чтобы получить путь к текущему модулю.


7

Python

path = os.path.dirname(__file__)

Это получает путь к текущему модулю.


5

Objective-C Cocoa (Mac OS X, я не знаю особенностей iPhone):

NSString * applicationPath = [[NSBundle mainBundle] bundlePath];

2
В моем приложении для Mac OSX я искал фактический путь к исполняемому файлу (для включения в список) и использовал это: NSString * executablePath = [[NSBundle mainBundle] executablePath]; - также существует версия «исполняемого URL» для возврата URL-адреса вместо строки
Тодд

4

В Java есть два способа найти путь к приложению. Один из них - использовать System.getProperty:

System.getProperty("user.dir");

Другая возможность - использование java.io.File:

new java.io.File("").getAbsolutePath();

Еще одна возможность использует отражение:

getClass().getProtectionDomain().getCodeSource().getLocation().getPath();

1
Обратите внимание, что это немного вводит в заблуждение / сбивает с толку. Три приведенных вами метода могут дать совершенно разные результаты!
Zarkonnen

Зарконнен: Вы правы, но, как следует из моего исходного сообщения, я не эксперт. Это вики сообщества. Пожалуйста, не стесняйтесь редактировать / исправлять мой ответ!
Конрад Рудольф

СОВЕТ: Обычно путь не нужно указывать, если вы хотите получить доступ к файлу в текущем рабочем каталоге, например: file = new File ("file.cfg"); Просто убедитесь, что в рабочем каталоге всегда указывается местоположение вашего приложения во время инициализации или с помощью ярлыка приложения.
lepe

@lepe Не устанавливайте рабочий каталог при запуске, это имеет некоторые нежелательные последствия, такие как указание в некоторых диалоговых окнах выбора файлов по умолчанию пути к приложению, а не рабочего каталога, выбранного пользователем.
Конрад Рудольф

1
Две основные проблемы с последним подходом. Во-первых, ProtectionDomain.getCodeSource () может возвращать null . Во-вторых, URL.getPath () не возвращает имя файла, он просто возвращает (возможно, экранированный) путь к URL-адресу. C:\Program Files\ExampleAppпредставлен в форме URL как file:/C:/Program%20Files/ExampleApp, для которого возвращает getPath () "/C:/Program%20Files/ExampleApp", которого явно не существует. Единственный правильный способ преобразовать URL-адрес в файл - это new File(url.toURI()).
VGR 01

4

В VB6 вы можете получить путь к приложению, используя App.Pathсвойство.

Обратите внимание, что это не будет завершаться \ИСКЛЮЧЕНИЕМ, когда приложение находится в корне диска.

В среде IDE:

?App.Path
C:\Program Files\Microsoft Visual Studio\VB98

4

В .Net вы можете использовать

System.IO.Directory.GetCurrentDirectory

чтобы получить текущий рабочий каталог приложения, а в VB.NET, в частности, вы можете использовать

My.Application.Info.DirectoryPath

чтобы получить каталог exe.


3

Delphi

В приложениях Windows:

Unit Forms;
path := ExtractFilePath(Application.ExeName);

В консольных приложениях:

Независимо от языка, первым параметром командной строки является полное имя исполняемого файла:

Unit System;
path := ExtractFilePath(ParamStr(0));


2

Unix

В unix можно найти путь к исполняемому файлу, который был запущен с использованием переменных среды. Это не обязательно абсолютный путь, поэтому вам нужно будет объединить текущий рабочий каталог (в оболочке pwd:) и / или переменную PATH со значением 0-го элемента среды.

Однако значение ограничено в unix, так как исполняемый файл может, например, вызываться через символическую ссылку, и только начальная ссылка используется для переменной среды. В целом приложения в unix не очень надежны, если они используют это для каких-либо интересных вещей (например, для загрузки ресурсов). В unix обычно используются жестко запрограммированные местоположения для вещей, например файл конфигурации, в /etcкотором указаны местоположения ресурсов.



2

В PHP :

<?php
  echo __DIR__; //same as dirname(__FILE__). will return the directory of the running script
  echo $_SERVER["DOCUMENT_ROOT"]; // will return the document root directory under which the current script is executing, as defined in the server's configuration file.
  echo getcwd(); //will return the current working directory (it may differ from the current script location).
?>

2

в Android это

getApplicationInfo().dataDir;

чтобы получить SD-карту, я использую

Environment.getExternalStorageDirectory();
Environment.getExternalStoragePublicDirectory(String type);

где последний используется для хранения определенного типа файла (аудио / фильмы и т. д.). У вас есть константы для этих строк в классе Environment.

По сути, для всего, что связано с приложением, используйте класс ApplicationInfo и для всего, что связано с данными на SD-карте / внешнем каталоге, используя класс Environment.

Документы: ApplicationInfo , Environment


2

В Tcl

Путь к текущему скрипту:

set path [info script]

Путь к оболочке Tcl:

set path [info nameofexecutable]

Если вам нужен каталог любого из них, выполните:

set dir [file dirname $path]

Получить текущий (рабочий) каталог:

set dir [pwd]

2

Ява:

На всех системах (Windows, Linux, Mac OS X) у меня работает только это:

public static File getApplicationDir() 
{
    URL url = ClassLoader.getSystemClassLoader().getResource(".");
    File applicationDir = null;
    try {
        applicationDir = new File(url.toURI());
    } catch(URISyntaxException e) {
        applicationDir = new File(url.getPath());
    }

    return applicationDir;
}

Это вызывает NPE, если приложение работает в файле JAR.
user207421

1

в Ruby следующий фрагмент кода возвращает путь к текущему исходному файлу:

path = File.dirname(__FILE__)

1

В CFML есть две функции для доступа к пути скрипта:

getBaseTemplatePath()
getCurrentTemplatePath()

Вызов getBaseTemplatePath возвращает путь к «базовому» сценарию, то есть к тому, который был запрошен веб-сервером.
Вызов getCurrentTemplatePath возвращает путь к текущему сценарию, то есть к тому, который в данный момент выполняется.

Оба пути являются абсолютными и содержат полный каталог + имя файла сценария.

Чтобы определить только каталог, используйте функцию getDirectoryFromPath( ... ) по результатам.

Итак, чтобы определить местоположение приложения в каталоге, вы можете:

<cfset Application.Paths.Root = getDirectoryFromPath( getCurrentTemplatePath() ) />

Внутри onApplicationStart мероприятия для вашегоApplication.cfc



Чтобы определить путь, по которому находится сервер приложений, на котором запущен ваш механизм CFML, вы можете получить доступ к командам оболочки с помощью cfexecute, поэтому (учитывая вышеупомянутые обсуждения pwd / etc) вы можете сделать:

Unix:

<cfexecute name="pwd"/>

для Windows создайте pwd.batсодержащий текст@cd , затем:

<cfexecute name="C:\docume~1\myuser\pwd.bat"/>

(Используйте variableатрибут cfexecuteдля сохранения значения вместо вывода на экран.)


1

В cmd (оболочка командной строки Microsoft)

Вы можете получить имя скрипта с помощью% * (может быть относительно pwd)

Это получает каталог сценария:

set oldpwd=%cd%
cd %0\..
set app_dir=%pwd%
cd %oldpwd%

Если вы обнаружите какие-либо ошибки, вы их найдете. Тогда исправьте или прокомментируйте.


1

Я выпустил https://github.com/gpakosz/whereami, который решает проблему на C и дает вам:

  • путь к текущему исполняемому файлу
  • путь к текущему модулю (отличается от пути к исполняемому файлу при вызове из общей библиотеки).

Он используется GetModuleFileNameWв Windows, анализирует /proc/self/mapsв Linux и Android и использует _NSGetExecutablePathили dladdrна Mac и iOS.


0

Примечание к ответу «20 выше только для Mac OSX: если исполняемый файл JAR преобразован в« приложение »через OSX JAR BUNDLER, то getClass (). GetProtectionDomain (). GetCodeSource (). GetLocation (); НЕ вернет текущий каталог приложения, но добавит в ответ внутреннюю структуру каталогов приложения. Эта внутренняя структура приложения - это / theCurrentFolderWhereTheAppReside / Contents / Resources / Java / yourfile

Возможно, это небольшая ошибка в Java. В любом случае, чтобы получить правильный ответ, нужно использовать один или два метода, и оба дадут правильный ответ, даже если приложение запущено, например, через ярлык, расположенный в другой папке или на рабочем столе.

Карл

SoundPimp.com

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