无法使用java将命令写入共享位置上的exe程序

时间:2012-07-23 10:11:53

标签: java exe runtime.exec

我在共享位置放置了一个exe程序。启动时不需要任何参数。当它在命令窗口中启动时,它会显示一个帮助菜单,其中包含可以使用它执行的命令列表,并以>结束,期望输入命令。我需要从该列表中执行一个名为TRIGGER的特定命令。到目前为止,这是我的,但它完全失败了。它既不显示进程的输出,也不从流中获取输入命令trigger

public void execute(){

    String cmd = "\\\\sharedLocation\\server\\adm.exe";
    p = Runtime.getRuntime().exec(cmd);

    InputStream in = p.getInputStream();
    OutputStream out = p.getOutputStream();

    BufferedReader br= new BufferedReader(new InputStreamReader(in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(out));

    bw.write("TRIGGER");            
    bw.flush();

    String output = "";
    while (!output.endsWith(">")) {     
        System.out.println("in loop");
        output = output + br.readLine(); 
    }

    System.out.println("Out"+output);


    out.close();            
    p.waitFor();
}

编辑:此程序启动了adm.exe,但似乎adm.exe是一个阻止进程。它无法打印“in loop”语句。但是,当我打开Windows任务管理器并终止adm.exe进程树时,它会显示在控制台上

in loopnull
in loopnullnull
in loopnullnullnull
in loopnullnullnullnull
in loopnullnullnullnullnull
in loopnullnullnullnullnullnull
in loopnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
in loopnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
Outnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull

2 个答案:

答案 0 :(得分:1)

不确定但......

<强>时序

我知道你的execute方法在while被阻塞,等待一些输出及其终结。直到你发送TRIGGER才会出现。

我会尝试

  1. 之前发送TRIGGER(您不会丢失任何数据,它会被缓冲)
  2. 在方法结束时使用p.waitFor()以避免退出直到p结束(好吧,无论如何,这样做)。
  3. 修改

    你的adm.exe是否需要用UTF-16编写的TRIGGER?因为如果您使用getBytes(),那就是您要发送的内容。如果您需要其他编码(如UTF-8或ASCII),请尝试使用getBytes("UTF-8")示例。

    <强>示例

    我应该这样做:

    public void execute() {
    
    String cmd = "\\\\sharedLocation\\server\\adm.exe";
    Process p = Runtime.getRuntime().exec(cmd);     
    
    // send TRIGGER before everything (I can't consume the response if I don't ask for it first)
    OutputStream out = p.getOutputStream();
    out.write("TRIGGER".getBytes());
    out.flush(); // flush to ensure it's sent, but don't close...
    
    InputStream in = p.getInputStream();
    
    String output = "";
    int c = 0;
    while (!output.endsWith(">")){
        c = in.read(); // you've eaten this when modified your code
        output+= (char)c; // I should change the way bytes convert to char, but that's another story
    }
    
    System.out.println(output);
    
    
    // optional: if I want to wait for p to finish
    p.waitFor();
    }
    

答案 1 :(得分:1)

一些一般性意见:

  1. 请勿使用Process,而是使用ProcessBuilder。如果您想做一些比启动外部流程更复杂的事情,请使用Commons Exec

  2. 如果您只是在命令行上键入TRIGGER而不按返回会发生什么?如果没有任何反应,请按Java返回:在out中换PrintStream并使用pw.println("TRIGGER")

  3. 由于您没有获得任何输出,可能该命令会注意到它没有从命令提示符启动并且表现不同?如果是这种情况,请使用cmd /c \\\\sharedLocation\\server\\adm.exe

  4. 运行它
  5. 始终使用列表/数组来提供命令参数,以避免出现特殊字符问题