2010-09-22 2 views
20

Есть ли способ начать процесс в Java? в .NET это делается с помощью, например:Запуск процесса в Java?

System.Diagnostics.Process.Start("processname"); 

Есть ли эквивалент в Java, так что я могу затем позволить пользователю найти приложение, а затем она будет работать на любой операционной системе?

ответ

23

http://www.rgagnon.com/javadetails/java-0014.html

import java.io.*; 
public class CmdExec { 

    public static void main(String args[]) { 
    try { 
     String line; 
     Process p = Runtime.getRuntime().exec 
     (System.getenv("windir") +"\\system32\\"+"tree.com /A"); 
     BufferedReader input = 
     new BufferedReader 
      (new InputStreamReader(p.getInputStream())); 
     while ((line = input.readLine()) != null) { 
     System.out.println(line); 
     } 
     input.close(); 
    } 
    catch (Exception err) { 
     err.printStackTrace(); 
    } 
    } 
} 

Вы можете получить локальный путь используя свойства Системы или аналогичный подход.

http://download.oracle.com/javase/tutorial/essential/environment/sysprop.html

+5

Обратите внимание, что вы должны использовать форму '.exec (String [])' метода , а не одна строка '.exec (String)' form, которая * не является процессором командной строки * - она ​​просто разбивается на пробелы. Они дают тот же результат для этого примера 'tree.com/A', но отличаются, если задано, например, имя файла, в котором есть пробелы. –

+2

Вы также должны очистить поток ошибок и, при необходимости, дождаться выходного значения процесса. –

18

См. Runtime.exec() и класс Process. В своей простейшей форме:

Process myProcess = Runtime.getRuntime().exec(command); 
... 

Обратите внимание, что вы также должны прочитать процесс вывода (например: myProcess.getInputStream()) - или процесс будет висеть на некоторых системах. Это может быть очень запутанным в первый раз и должно быть включено в любое введение в эти API. См. Ответ Джеймса П. для примера.

Вы также можете посмотреть в новый ProcessBuilder класса, что делает его легче изменить переменные среды и вызывать подпроцессов:

Process myProcess = new ProcessBuilder(command, arg).start(); 
... 
+0

Вы также должны читать выход процесса в - p.getInputStream() - или процесс будет висеть на некоторых системах. Это может быть очень запутанным в первый раз и должно быть включено в любое введение в эти API. См. Ответ Джеймса П. для примера. –

+0

@ Энди Спасибо. Я включил ваш комментарий в свой ответ, если вы не возражаете. – NullUserException

+0

Что делать, если медиаплеером по умолчанию является VLC, и я хочу, например, открыть «somevideo.avi», и я хочу, чтобы он использовал приложение по умолчанию, которое является vlc? – jmasterx

7

Библиотека классов Java представляет внешние процессы с помощью java.lang.Process класса. Процессы могут быть порождал с использованием java.lang.ProcessBuilder:

Process process = new ProcessBuilder("processname").start(); 

или старый интерфейс, предоставляемый перегруженных exec методами на java.lang.Runtime класса:

Process process = Runtime.getRuntime().exec("processname"); 

Оба они будут кодировать фрагменты будут порождать новый процесс, который обычно выполняется асинхронно и может взаимодействовать через результирующий объект Process. Если вам нужно проверить завершение процесса (или дождаться его завершения), не забудьте проверить, что значение выхода (код выхода), возвращенное на process.exitValue() или process.waitFor(), соответствует ожиданиям (0 для большинства программ), так как нет исключение вызывается, если процесс выходит из строя.

Также обратите внимание, что дополнительный код часто необходимо правильно управлять процессом входы/выходы, как описано в documentation for the Process class (курсив добавлен):

По умолчанию создается подпроцесс не имеет своего собственного терминала или консоль. Все его стандартные операции ввода-вывода (т. Е. Stdin, stdout, stderr) будут перенаправлены на родительский процесс, где к ним можно получить доступ через потоки, полученные с помощью методов getOutputStream(), getInputStream() и getErrorStream(). Родительский процесс использует эти потоки для подачи ввода и получения вывода из подпроцесса. Поскольку некоторые собственные платформы обеспечивают ограниченный размер буфера для стандартных потоков ввода и вывода, отказ в быстрой записи потока ввода или чтение выходного потока подпроцесса может привести к блокировке подпроцесса или даже к взаимоблокировке.

Один из способов, чтобы убедиться, что I/O обработан правильно и что значение выхода указует на успех использовать библиотеку как jproc, которая занимается тонкостями захвата стандартного вывода и стандартного потока ошибок, и предлагает простой синхронный интерфейс запускать внешние процессы:

ProcResult result = new ProcBuilder("processname").run(); 

jproc доступна через мавена центральный:

<dependency> 
     <groupId>org.buildobjects</groupId> 
     <artifactId>jproc</artifactId> 
     <version>2.2.0</version> 
</dependency> 
0

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

Process p = Runtime.getRuntime().exec(System.getenv("windir") + "\\system32\\" + "calc.exe"); 
Смежные вопросы