Java открыть другую программу

Русские Блоги

При запуске внешней программы на Java используется метод exec () класса java.lang.Runtime. Этот метод возвращает класс Process.
Если вы хотите захватить вывод работающей программы, используйте класс Process. Класс Process имеет три метода:
Process.getOutputStream(), Process.getInputStream(), Process.getErrorStream().
Соответствует стандарту stdin, stdout, stderr. Поэтому, если вы хотите захватить вывод программы, вы должны использовать
Process.getInputStream()。

Пример, который я привел ниже, состоит в том, чтобы запустить программу ping и затем вывести ее вывод на экран.
Эффект такой же, как прямой запуск программы ping.
Для примеров использования других методов класса Process, пожалуйста, скачайте примеры API библиотеки классов jdk1.1, которые я предоставил.

 import java.io.*; 
class Main <
public static void main(String[] args) <
try <
String cmd = "ping ";
String param ="202.112.58.200";
Process child = Runtime.getRuntime().exec(cmd+param);
// получить вывод ping
InputStream child_in = child.getInputStream();
int c;
while ((c = child_in.read()) != -1) <
// System.out.println("kkk");
System.out.print((char)c);
>
child_in.close();
> catch (IOException e) <
System.err.println(e);
>
>
>

Два других простых примера: вызов браузера ie с помощью java (iexplore.exe и файл класса находятся в одном каталоге)


import java.io.*;
class Main <
public static void main(String[] args) <
try <
String cmd = "iexplore.exe ";
String param ="http://www.java3z.com/";
Process child = Runtime.getRuntime().exec(cmd+param);
// получить вывод ping

> catch (IOException e) <
System.err.println(e);
>
>
>
import java.io.*;
public class ProcessTest public static void main(String args[]) throws IOException Process p = new ProcessBuilder("iexplore.exe","http://www.java3z.com/").start();
>
>

Источник

>рабочие заметки

Недавно в DataGuard пришлось разбираться с запуском внешних программ из java. Некоторые вещи оказались довольно нетривиальны, так что я решил поделиться.

На первый взгляд, все достаточно просто — для простых случаев есть Runtime.exec() , если нужно настроить параметры среды для запуска — есть ProcessBuilder . В любом случае получаем объект Process, у которого вызываем Process.waitFor() , чтобы дождаться завершения — и, вроде бы, все?

К сожалению, ничего подобного. Несмотря на то, что API выглядит просто и очевидно, корректное его использование совсем не просто, и не очевидно. Какие конкретно подводные камни нас ждут?

Главный из них — потоки ввода-вывода (IO streams). У порождаемого процесса нет терминала, к которому он привязан, его stdin, stdout, stderr выдаются порождающему процессу — то есть, нам. Причем обрабатывать их — наша обязанность. Потоки, созданные ОС имеют ограниченный размер буфера. Если, к примеру, буфер stdout для запущенного процесса заполнен, со стороны java никто его не читает (==не освобождает) а процесс настойчиво хочет что-то вывести — то процесс просто окажется заблокирован на IO, и будет ждать, пока stdout кто-нибудь освободит. Если мы не предусмотрели в java код, читающий process.getInputStream() — получается стандартный дедлок: мы ждем завершения процесса, процесс ждет нас.

Самый опасный момент здесь в том, что размер буфера заранее не определен. Поэтому приложение может в одном случае работать как часы, а в другом — непонятно зависать.

Конкретный пример: в обычном, штатном режиме работы внешний процесс выдает одну-единственную строчку «Ок» и завершается. Строчка вполне влезает в буфер, поэтому код

final Process p = Runtime.getRuntime().exec( "my-script.bat" ); final int retCode = p.waitFor();

работает корректно. Но наступает день Х, когда звезды складываются неудачно. И процесс завершается с ошибкой. И, как и положено уважающей себя программе, старается эту ошибку максимально подробно описать. И пытается вывести в stdout простыню текста, превышающую размер буфера. Вуаля — процесс ждет на выводе, java-программа — на process.waitFor()

Читайте также:  Image link styling css

На мой взгляд — это пример плохо спроектированного API. Простая вещь — запустить внешний процесс не заморачиваясь с его выводом — делается весьма нетривиально. Более того, из самого API это никак не следует. Да, в документации к Process это прописано, но я считаю, что хороший API это такой, использование которого, по крайней мере для простых задач, очевидно без документации. Можно было бы дополнить контракт, например, так: «если клиент не запросил process.getInputStream() / process.getErrorStream() до вызова process.waitFor() — stdout/stderr внешнего процесса автоматически перенаправляются вникуда».

Но наши друзья из Sun этого не сделали, так что приходится отдуваться самим: ProcessRunner

Что делает: берет сконфигурированный ProcessBuilder, создает внешний процесс, запускает асинхронно «помпы», прокачивающие его потоки ввода-вывода либо в пустоту (если пользователь ничего не задал) либо из/в заранее заданные потоки. Метод ProcessRunner.execute() блокируется пока либо процесс не завершится, либо пока не будет вызван ProcessRunner.interrupt() . Пример использования:

final ProcessBuilder pb = new ProcessBuilder("my-script.bat"); final ExecutorService pool = Executors.newFixedThreadPool(3); // нужно минимум 3 свободных потока в пуле final ProcessRunner pwd = new ProcessRunner( "run", pb, pool ); pwd.execute(); final int retCode = pwd.getReturnCode(); . pool.shutdown();

В этом примере ввод-вывод my-script.bat будет просто выброшен. Другой пример:

final ProcessBuilder pb = . ; final ProcessRunner pwd = new ProcessRunner( "run", pb, POOL ); final ByteArrayOutputStream out = new ByteArrayOutputStream(); final ByteArrayOutputStream err = new ByteArrayOutputStream(); pwd.setOutputStream( out ); pwd.setErrorStream( err ); pwd.execute(); assertEquals( 0, pwd.getReturnCode() ); final byte[] output = out.toByteArray(); final byte[] errors = err.toByteArray();

Здесь stdout/stderr будут считаны в предоставленные нами потоки. Обратите внимание, что если флаг ProcessBuilder.redirectErrorStream() выставлен в true, то stderr будет слит с stdout, и errors будет пуст.

Больше примеров использования можно посмотреть в тестах ProcessRunnerTest

Источник

Java открыть другую программу

We use cookies to collect and analyze information on site performance and usage, to provide social media features and to enhance and customize content and advertisements.

Be sure to read this Javaworld article. It describes the various pitfalls related to the Runtime.exec() method.

Using Runtime.exec()
package com.rgagnon.howto; import java.io.*; public class Exec < public static void main(String args[]) < try < String line; Process p = Runtime.getRuntime().exec("cmd /c dir"); BufferedReader bri = new BufferedReader (new InputStreamReader(p.getInputStream())); BufferedReader bre = new BufferedReader (new InputStreamReader(p.getErrorStream())); while ((line = bri.readLine()) != null) < System.out.println(line); >bri.close(); while ((line = bre.readLine()) != null) < System.out.println(line); >bre.close(); p.waitFor(); System.out.println("Done."); > catch (Exception err) < err.printStackTrace(); >> >

The next example, launch CMD.EXE, grab stdin/stdout and push to stdin command to be interpreted by the shell.

String line; OutputStream stdin = null; InputStream stderr = null; InputStream stdout = null; // launch EXE and grab stdin/stdout and stderr Process process = Runtime.getRuntime ().exec ("/folder/exec.exe"); stdin = process.getOutputStream (); stderr = process.getErrorStream (); stdout = process.getInputStream (); // "write" the parms into stdin line = "param1" + "\n"; stdin.write(line.getBytes() ); stdin.flush(); line = "param2" + "\n"; stdin.write(line.getBytes() ); stdin.flush(); line = "param3" + "\n"; stdin.write(line.getBytes() ); stdin.flush(); stdin.close(); // clean up if any output in stdout BufferedReader brCleanUp = new BufferedReader (new InputStreamReader (stdout)); while ((line = brCleanUp.readLine ()) != null) < //System.out.println ("[Stdout] " + line); >brCleanUp.close(); // clean up if any output in stderr brCleanUp = new BufferedReader (new InputStreamReader (stderr)); while ((line = brCleanUp.readLine ()) != null) < //System.out.println ("[Stderr] " + line); >brCleanUp.close();
Launch a Windows CMD (or BAT) file and retrieve the errorlevel or exitcode
// win xp import java.io.*; public class CmdExec < public static void main(String argv[]) < try < String line; Process p = Runtime.getRuntime().exec("test.cmd"); p.waitFor(); System.out.println(p.exitValue()); >catch (Exception err) < err.printStackTrace(); >> >
Launch a Unix script
String[] cmd = hello">; Runtime.getRuntime().exec(cmd);
Using the ProcessBuilder

Since 1.5, the ProcessBuilder class provides more controls overs the process to be started. It’s possible to set a starting directory.

import java.io.*; import java.util.*; public class CmdProcessBuilder < public static void main(String args[]) throws InterruptedException,IOException < Listcommand = new ArrayList(); command.add(System.getenv("windir") +"\\system32\\"+"tree.com"); command.add("/A"); ProcessBuilder builder = new ProcessBuilder(command); Map environ = builder.environment(); builder.directory(new File(System.getenv("temp"))); System.out.println("Directory : " + System.getenv("temp") ); final Process process = builder.start(); InputStream is = process.getInputStream(); InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line; while ((line = br.readLine()) != null) < System.out.println(line); >System.out.println("Program terminated!"); > >
Windows rundll32 utility

Windows File association
Any program using the Windows file association mechanism can be started with the rundll32 utility.

// "file" is the filename of the data file // ex. myresume.doc // to start Word if the doc extension is associated with it. Runtime.getRuntime().exec ("rundll32 SHELL32.DLL,ShellExec_RunDLL " + file.getAbsolutePath());

See also this HowTo about the new Desktop API, the recommended solution (but you need JDK1.6).
See also this one to open the default browser.

Читайте также:  Java удалить все пробелы строки

The following example start a Dial-up connection on the Win plateform :

[Dialup.java] public class Dialup < public static void main(String[] args) throws Exception < Process p = Runtime.getRuntime() .exec("rundll32.exe rnaui.dll,RnaDial MyConnection"); p.waitFor(); System.out.println("Done."); >>

You still need to press ENTER to CONNECT, there is an option in the Connection properties to connect automatically.

On NT and W2K, rnaui.dll is not available. Use rasdial.exe instead.

rasdial "connection name" rasdial "connection name" /d to drop rasdial /? for more options
PDF (Windows only)
PDF (Mac only)
Path to executable with spaces in them

You can include a path for the program to be executed. On the Win plateform, you need to put the path in quotes if the path contains spaces.

If you need to pass arguments, it’s safer to a String array especially if they contain spaces.

String[] cmd = < "myProgram.exe", "-o=This is an option" >; Runtime.getRuntime().exec(cmd);

If using the start command and the path of the file to be started contains a space then you must specified a title to the start command.

String fileName = "c:\\Applications\\My Documents\\test.doc"; String[] commands = ; Runtime.getRuntime().exec(commands);
VBSCRIPT
// Win9x Runtime.getRuntime().exec("start myscript.vbs"); // WinNT Runtime.getRuntime().exec("cmd /c start myscript.vbs"); or // with a visible console Runtime.getRuntime().exec("cscript myscript.vbs"); // with no visible console Runtime.getRuntime().exec("wscript myscript.vbs");
HTML Help (Windows only)
Runtime.getRuntime().exec("hh.exe myhelpfile.chm");
Start Excel
import java.io.IOException; class StartExcel < public static void main(String args[]) throws IOException < Runtime.getRuntime().exec("cmd /c start excel.exe"); >>
import java.io.IOException; class StartExcel < public static void main(String args[]) throws IOException < String fileName = "c:\\temp\\xls\\test2.xls"; String[] commands = ; Runtime.getRuntime().exec(commands); > >

It’s important to pass a dummy title to the Windows start command where there is a possibility that the filename contains a space. It’s a feature.

Читайте также:  Html window document height
Start a Windows application under another account

You use the RUNAS command from the command line to start an application under another account (not available with XP Home edition). There are many switches that can enhance the behaviour of RUNAS. Typing «runas /?» from the command prompt gets you all the options.

String commands [] = new String [] < "CMD.EXE", "/C", "RUNAS /profile /savecred /user:" + "administrator" + " " + "regedit.exe" >; Runtime.getRuntime().exec(commands);

/SaveCred option allows you to save a password for that account and then reuse it later. For example, The command runas /savecred /user:administrator regedit.exe prompts for the password, and then Regedit runs. Next time you use the same command, there is no password prompt.

One potential problem is that when /SaveCred saves the credentials it saves it for whenever RUNAS invokes that user account. This can be a huge security risk so be careful using it!

RUNAS capability can be disabled by editing the Registry or by disabling the RUNAS or Secondary Logon Services. The appropriate registry key is HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\Explorer , create a new DWORD value named HideRunAsVerb and assign it a value of 1 to disable Run as.

RUNAS doesn’t work when used from a Windows service.

Windows : execute something in Program Files

We want to execute the textpad editor located in C:\Program Files\TextPad 4 but without hard coding the path since it can be different for a localized version of Windows.

We simply extract to environnment variable called %programfiles% and build the complete path from there.

public class Exec < static String WIN_PROGRAMFILES = System.getenv("programfiles"); static String FILE_SEPARATOR = System.getProperty("file.separator"); public static void main(String[] args) throws Exception < String[] commands = ; Runtime.getRuntime().exec(commands); > >

Источник

Запуск стороннего приложения?

Необходимо из Java программы запустить стороннее приложение БЕЗ ожидания закрытия запущенного приложения.

запустили jar’ник — открылся блокнот (windows среда) и завершилась работа jarника

Оценить 1 комментарий

А в чём, собственно, проблема? Процесс запущенный ProcessBuilder -ом завершается по выходе из запускающего приложения? Или вы не знаете каким вызовом WinAPI воспользоваться?

Разбирайтесь со своей программой. Зачем она чего-то ждёт? Она вызывает Process.waitFor() ? Потому что иначе вызывающая программа не ожидает завершения вызванной. Вот код для примера:

import java.io.IOException; public class Run < public static void main(String[] args) < try < new ProcessBuilder("/usr/bin/kwrite").start(); >catch (IOException e) < e.printStackTrace(); >> > 

Запускает программу и завершает работу (в Linux). Подставьте запуск notepad и проверьте. Неужели Java-программа не завершит работу?

public static void main(String[] args) <
try <
new ProcessBuilder(«notepad»).start();
> catch (IOException e) <
e.printStackTrace();
>
>

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

Виндопроблемы. Посмотрите, может это поможет. В общем, вам нужно найти аналог nohup для windows. Может start /p notepad вместо notepad поможет?

Источник

Оцените статью