繁体   English   中英

在Java中运行bat文件并等待2

[英]Run bat file in Java and wait 2

这是我另一个问题的跟进问题: 在Java中运行bat文件并等待

我将其作为一个单独的问题发布的原因是,我已经问过的问题得到了正确回答。 通过一些研究,我发现我的问题是我所遇到的问题所独有的,因此我决定创建一个新问题。 由于它们关系密切,因此请先阅读该问题,然后再继续进行此问题。

运行建议的代码会在waitFor调用时阻止程序。 经过一番研究,我发现,如果您的进程具有需要处理的输出,则waitFor方法会阻塞,因此您应该首先清空输出流和错误流。 我做了这些事情,但我的方法仍然受阻。 然后,我发现一个建议,可以在等待exitValue方法返回过程的退出值时简单地循环并处理抛出的异常(如果不是),暂停一会儿,以免消耗掉所有CPU。 我这样做:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class Test {

 public static void main(String[] args) {
  try {
   Process p = Runtime.getRuntime().exec(
     "cmd /k start SQLScriptsToRun.bat" + " -UuserName -Ppassword"
       + " projectName");
   final BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
   final BufferedReader error = new BufferedReader(new InputStreamReader(p.getErrorStream()));
   new Thread(new Runnable() {

    @Override
    public void run() {
     try {
      while (input.readLine()!=null) {}
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
   }).start();
   new Thread(new Runnable() {

    @Override
    public void run() {
     try {
      while (error.readLine()!=null) {}
     } catch (IOException e) {
      e.printStackTrace();
     }
    }
   }).start();
   int i = 0;
   boolean finished = false;
   while (!finished) {
    try { 
     i = p.exitValue();
     finished = true;
    } catch (IllegalThreadStateException e) {
     e.printStackTrace();
     try {
      Thread.sleep(500);
     } catch (InterruptedException e1) {
      e1.printStackTrace();
     }
    }
   }
   System.out.println(i);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
}

但是我的过程不会结束! 我不断收到此错误:

java.lang.IllegalThreadStateException: process has not exited

关于为什么我的流程无法退出的任何想法? 还是您有任何库建议使用适当的批处理文件,然后等待执行完成?

使用/c开关而不是/k来启动cmd并摆脱start

Process p = Runtime.getRuntime().exec( 
   "cmd /c SQLScriptsToRun.bat" + " -UuserName -Ppassword" 
   + " projectName");

/k告诉cmd :“运行该命令,然后保持打开状态”, /c则显示“运行该命令,然后退出”。

/k供交互式使用,您需要初始化批处理文件,然后仍使用控制台。

但是,这里的主要问题是您正在使用start创建另一个进程 要运行批处理文件,这是完全没有必要的,并且可以防止您知道批处理何时完全运行,因为Java引用了您启动的原始cmd进程,而不是您使用start生成的cmd进程。

原则上,现在看起来如下所示:

  1. Java程序启动
  2. Java程序运行cmd并指示其运行start foo.bat并保持打开状态以进行交互式输入( /k
  3. Java存储进程ID(PID 42),以便以后引用该进程

    • cmd (PID 42)启动
    • cmd (PID 42)运行start foo.bat
    • start foo.bat启动cmd另一个实例,因为这是运行批处理文件时应执行的操作
      • cmd (PID 57005)启动
      • cmd (PID 57005)运行foo.bat
      • cmd (PID 57005)退出(这表示您想了解的事件)
    • cmd (PID 42)显示提示并听从等待输入(对于他们而言,未知的提示是用户从未看到过提示,并且永远不会输入...但是cmd (PID 42)等待...)
  4. Java喜欢知道该过程是否完成并检查PID 42

  5. 是的,它仍然在那里。 怎么办?

您想要的(以及上述更改将完成的工作)是:

  1. Java程序启动
  2. Java程序运行cmd并指示其运行foo.bat并在运行命令( /c )后关闭
  3. Java存储进程ID(PID 42),以便以后引用该进程

    • cmd (PID 42)启动
    • cmd (PID 42)运行foo.bat
    • cmd (PID 42)退出
  4. Java喜欢知道该过程是否完成并检查PID 42

  5. 糟糕,该过程已消失,批处理文件已运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM