从Java执行另一个应用程序

我需要执行一个执行另一个Java应用程序的批处理文件。 我不关心它是否成功执行,我不必捕获任何错误。

是否可以使用ProcessBuilder执行此操作? 如果我没有捕获错误会有什么后果?

但是,我的要求只是执行另一个Java应用程序。

Runtime.getRuntime().exec()方法非常麻烦,您很快就会发现。

看看Apache Commons Exec项目。 它抽象了许多与使用Runtime.getRuntime().exec()ProcessBuilder API相关的常见问题。

它很简单:

 String line = "myCommand.exe"; CommandLine commandLine = CommandLine.parse(line); DefaultExecutor executor = new DefaultExecutor(); executor.setExitValue(1); int exitValue = executor.execute(commandLine); 

是的,可以使用ProcessBuilder。

ProcessBuilder示例:

 import java.io.*; import java.util.*; public class CmdProcessBuilder { public static void main(String args[]) throws InterruptedException,IOException { List command = new ArrayList(); command.add(args[0]); ProcessBuilder builder = new ProcessBuilder(command); Map environ = builder.environment(); 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!"); } } 

检查以下示例:

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

http://www.java-tips.org/java-se-tips/java.util/from-runtime.exec-to-processbuilder.html

我假设您知道如何使用ProcessBuilder执行命令。

从Java执行命令总是应该从进程中读取stdout和stderr流。 否则,可能会发生缓冲区已满并且进程无法继续,因为写入stdout或stderr块。

以下是如何使用ProcessBuilder执行远程应用程序的示例。 由于您不关心输入/输出和/或错误,因此您可以执行以下操作:

 List args = new ArrayList(); args.add ("script.bat"); // command name args.add ("-option"); // optional args added as separate list items ProcessBuilder pb = new ProcessBuilder (args); Process p = pb.start(); p.waitFor(); 

waitFor()方法将一直等到进程结束后再继续。 此方法返回进程的错误代码,但由于您不关心它,我没有将它放在示例中。

您可以使用执行批处理指令或任何其他应用程序

 Runtime.getRuntime().exec(cmd); 
  • cmd是命令或te应用程序路径。

此外,你可以等待执行并获得返回代码(以检查它是否正确执行)与此代码:

  Process p = Runtime.getRuntime().exec(cmd); p.waitFor(); int exitVal = p.exitValue(); 

您可以在http://www.rgagnon.com/javadetails/java-0014.html找到不同类型呼叫的完整说明

我知道这是一个较旧的线程,但是我觉得我可能有必要加入我的实现,因为我发现这个线程试图做与OP相同的事情,除了Root级访问,但没有真正找到解决方案我在寻找。 下面的方法创建一个静态根级别shell,用于执行命令而不考虑错误检查,或者即使命令执行成功。

我用它是我创建的Android手电筒应用程序,允许将LED设置为不同的亮度级别。 通过删除所有错误检查和其他绒毛,我可以让LED在短至3毫秒内切换到指定的亮度级别,这打开了LightTones(带光的RingTones)的大门。 有关应用程序本身的更多详细信息,请访问: http : //forum.xda-developers.com/showthread.php?t = 2659842

以下是整个课程。

 public class Shell { private static Shell rootShell = null; private final Process proc; private final OutputStreamWriter writer; private Shell(String cmd) throws IOException { this.proc = new ProcessBuilder(cmd).redirectErrorStream(true).start(); this.writer = new OutputStreamWriter(this.proc.getOutputStream(), "UTF-8"); } public void cmd(String command) { try { writer.write(command+'\n'); writer.flush(); } catch (IOException e) { } } public void close() { try { if (writer != null) { writer.close(); if(proc != null) { proc.destroy(); } } } catch (IOException ignore) {} } public static void exec(String command) { Shell.get().cmd(command); } public static Shell get() { if (Shell.rootShell == null) { while (Shell.rootShell == null) { try { Shell.rootShell = new Shell("su"); //Open with Root Privileges } catch (IOException e) { } } } return Shell.rootShell; } } 

然后我的应用程序中的任何地方运行命令,例如更改LED亮度,我只需调用:

 Shell.exec("echo " + bt.getLevel() + " > "+ flashfile); 

如果你不关心返回值,你可以使用Runtime.getRuntime().exec("path.to.your.batch.file");

下面的代码片段编写用于使用ProcessBuilder编译和运行外部JAVA程序,我们可以运行任何外部程序。 确保必须在OS环境中设置JAVA_HOME。 看到更多

 package com.itexpert.exam; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; public class JavaProcessBuilder { /** * Provide absolute JAVA file path */ private static final String JAVA_FILE_LOCATION = "D:\\Test.java"; public static void main(String args[]) throws IOException{ String command[] = {"javac",JAVA_FILE_LOCATION}; ProcessBuilder processBuilder = new ProcessBuilder(command); Process process = processBuilder.start(); /** * Check if any errors or compilation errors encounter then print on Console. */ if( process.getErrorStream().read() != -1 ){ print("Compilation Errors",process.getErrorStream()); } /** * Check if javac process execute successfully or Not * 0 - successful */ if( process.exitValue() == 0 ){ process = new ProcessBuilder(new String[]{"java","-cp","d:\\","Test"}).start(); /** Check if RuntimeException or Errors encounter during execution then print errors on console * Otherwise print Output */ if( process.getErrorStream().read() != -1 ){ print("Errors ",process.getErrorStream()); } else{ print("Output ",process.getInputStream()); } } } private static void print(String status,InputStream input) throws IOException{ BufferedReader in = new BufferedReader(new InputStreamReader(input)); System.out.println("************* "+status+"***********************"); String line = null; while((line = in.readLine()) != null ){ System.out.println(line); } in.close(); } 

}

我可以看到有一个比apache commons exec库更好的库。 您可以使用Java Secure Shell(JSch)执行您的工作。

我有同样的问题。 我用JSch来解决这个问题。 Apache commons在另一台服务器上运行命令时遇到了一些问题。 加上JSch给了我结果和错误InputStreams。 我发现它更优雅。 样本解决方案可以在这里找到: http : //wiki.jsch.org/index.php?Manual%2FExamples%2FJschExecExample

  import java.io.InputStream; import java.io.BufferedReader; import java.io.InputStreamReader; import org.apache.commons.exec.*; import com.jcraft.*; import com.jcraft.jsch.JSch; import com.jcraft.jsch.Session; import com.jcraft.jsch.ChannelExec; import java.util.Arrays; import java.util.List; import java.util.ArrayList; import java.util.HashMap; public class exec_linux_cmd { public HashMap> exec_cmd ( String USERNAME, String PASSWORD, String host, int port, String cmd) { List result = new ArrayList(); List errors = new ArrayList(); HashMap> result_map = new HashMap>(); //String line = "echo `eval hostname`"; try{ JSch jsch = new JSch(); /* * Open a new session, with your username, host and port * Set the password and call connect. * session.connect() opens a new connection to remote SSH server. * Once the connection is established, you can initiate a new channel. * this channel is needed to connect and remotely execute the program */ Session session = jsch.getSession(USERNAME, host, port); session.setConfig("StrictHostKeyChecking", "no"); session.setPassword(PASSWORD); session.connect(); //create the excution channel over the session ChannelExec channelExec = (ChannelExec)session.openChannel("exec"); // Gets an InputStream for this channel. All data arriving in as messages from the remote side can be read from this stream. InputStream in = channelExec.getInputStream(); InputStream err = channelExec.getErrStream(); // Set the command that you want to execute // In our case its the remote shell script channelExec.setCommand(cmd); //Execute the command channelExec.connect(); // read the results stream BufferedReader reader = new BufferedReader(new InputStreamReader(in)); // read the errors stream. This will be null if no error occured BufferedReader err_reader = new BufferedReader(new InputStreamReader(err)); String line; //Read each line from the buffered reader and add it to result list // You can also simple print the result here while ((line = reader.readLine()) != null) { result.add(line); } while ((line = err_reader.readLine()) != null) { errors.add(line); } //retrieve the exit status of the remote command corresponding to this channel int exitStatus = channelExec.getExitStatus(); System.out.println(exitStatus); //Safely disconnect channel and disconnect session. If not done then it may cause resource leak channelExec.disconnect(); session.disconnect(); System.out.println(exitStatus); result_map.put("result", result); result_map.put("error", errors); if(exitStatus < 0){ System.out.println("Done--> " + exitStatus); System.out.println(Arrays.asList(result_map)); //return errors; } else if(exitStatus > 0){ System.out.println("Done -->" + exitStatus); System.out.println(Arrays.asList(result_map)); //return errors; } else{ System.out.println("Done!"); System.out.println(Arrays.asList(result_map)); //return result; } } catch (Exception e) { System.out.print(e); } return result_map; } //CommandLine commandLine = CommandLine.parse(cmd); //DefaultExecutor executor = new DefaultExecutor(); //executor.setExitValue(1); //int exitValue = executor.execute(commandLine); public static void main(String[] args) { //String line = args[0]; final String USERNAME ="abc"; // username for remote host final String PASSWORD ="abc"; // password of the remote host final String host = "3.98.22.10"; // remote host address final int port=22; // remote host port HashMap> result = new HashMap>(); //String cmd = "echo `eval hostname`"; // command to execute on remote host exec_linux_cmd ex = new exec_linux_cmd(); result = ex.exec_cmd(USERNAME, PASSWORD , host, port, cmd); System.out.println("Result ---> " + result.get("result")); System.out.println("Error Msg ---> " +result.get("error")); //System.out.println(Arrays.asList(result)); /* for (int i =0; i < result.get("result").size();i++) { System.out.println(result.get("result").get(i)); } */ } } 

编辑1:为了找到在Unix上执行的进程(如果它是一个长期运行的进程),请使用ps -aux | grep java ps -aux | grep java 。 应该与您正在执行的unix命令一起列出进程ID。

你可以简单地使用Runtime.exec()