我想从java中执行外部.exe程序。 .exe是一个CLI应用程序,它在运行时接收输入(scanf())并根据输入输出。我可以使用
调用程序从java执行Process p = Runtime.getRuntime().exec("cmd /c start a.exe");
而不是
Process p = Runtime.getRuntime().exec("cmd /c start a.exe");
但我认为也可以从java中调用程序。我用C ++编写的整个程序只需要一个用java编写的GUI。有几点需要注意:=
1)与.exe的通信应该是运行时(不是通过main(args)) 2)java程序应该将输出存储在一些变量/面板中以备将来使用 3)要执行的程序可能不同(例如,用户可以选择根本不接受任何输入的.exe) ........所以基本上java GUI将充当RuntimeEnv
public void runEXE() {
String s = null;
try {
Process p = Runtime.getRuntime().exec("cmd /c a.exe");
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
我知道有很多关于这个话题的问题。但我发现它们中的任何一个都没用。
答案 0 :(得分:3)
我使用的相当难看的小功能。这会将命令传递给Runtime.getRuntime().exec
,然后将结果保存到String中,并在结尾处返回String。您可以选择是否只需要最后一行(或所有输出)以及是否要从过程中保存stdout或stderr字符串。
private static String systemResult(String cmd, boolean append, boolean useErr)
{
String result = "";
try{
// spawn the external process
//printCmd(cmd);
Process proc = Runtime.getRuntime().exec(cmd);
LineNumberReader lnr1 = new LineNumberReader(new InputStreamReader(proc.getErrorStream()));
LineNumberReader lnr2 = new LineNumberReader(new InputStreamReader(proc.getInputStream()));
String line;
int done = 0;
while(lnr1 != null || lnr2 != null){
try{
if(lnr1.ready()){
if((line = lnr1.readLine()) != null){
//System.err.println("A:" +line);
if(useErr){
if(append) result = result + line + "\n";
else result = line;
}
}
}else if(done == 1){
done = 2;
}
}catch(Exception e1){
try{ lnr1.close(); }catch(Exception e2){}
lnr1 = null;
}
try{
if(lnr2.ready()){
if((line = lnr2.readLine()) != null){
//System.err.println("====>Result: " + line);
if(!useErr){
if(append) result = result + line + "\n";
else result = line;
}
}
}else if(done == 2){
break;
}
}catch(Exception e1){
try{ lnr2.close(); }catch(Exception e2){}
lnr2 = null;
}
try{
proc.exitValue();
done = 1;
}catch(IllegalThreadStateException itsa){}
}
if(lnr1 != null) lnr1.close();
if(lnr2 != null) lnr2.close();
try{
proc.waitFor();
}catch(Exception ioe){
}finally{
try{
proc.getErrorStream().close();
proc.getInputStream().close();
proc.getOutputStream().close();
}catch(Exception e){}
proc = null;
}
}catch(Exception ioe){
}
return result;
}
答案 1 :(得分:1)
我会查看JNI并使用某种类型的IPC与C ++项目进行通信。
<强>更新强>
JNI是Java与JRE运行的底层本机环境交互的一种方式。 Java程序启动时,此方法需要create a DLL that is loaded into the JRE。然后,此JNI DLL将包含一个方法,该方法可以在Java程序中调用,该方法将数据传递到JNI DLL,然后可以通过命名管道或共享内存与C ++项目进行通信。
使用CreateNamedPipe Win32 API创建命名管道。在JNI DLL中,您最有可能创建server,在C ++项目中,您将创建client。请注意,服务器示例是多线程的,但为了简单起见,可以很容易地将其转换为单个线程模型。
请注意,这不是一项简单的任务。其他答案提供了一些更容易的方法,JNA并通过stdin将数据传递给C ++项目。
答案 2 :(得分:1)
您可以使用JNI作为@ linuxuser27建议,或者您可以使用SWIG来帮助实现从Java进行通信的过程 - &gt; C ++不那么痛苦。
答案 3 :(得分:1)
Google Protocol Buffers将是Java / C ++互操作性的一个很好的选择。
协议缓冲区是Google的 语言中立,平台中立, 用于序列化的可扩展机制 结构化数据 - 想想XML,但是 更小,更快,更简单。您 定义您希望数据的方式 结构化一次,然后你可以使用 特殊生成的源代码 轻松编写和阅读您的结构化 来往各种数据的数据 流和使用各种各样的 语言 - Java,C ++或Python。
答案 4 :(得分:0)
有几件事:
答案 5 :(得分:0)
您可以直接执行.exe程序。您只需提供完整路径即可。相对路径也可以。
您可以使用管道与外部流程进行交互:Sending Input to a Command,Reading Output from a Command
答案 6 :(得分:0)