当前位置: 首页 > 面试题库 >

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

宰父才
2023-03-14
问题内容

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

运行建议的代码会在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

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


问题答案:

启动cmd/c交换机而不是/k和摆脱的start

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

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

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

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

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

  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)等待…)
    • Java喜欢知道该过程是否完成并检查PID 42
  4. 是的,它仍然在那里。怎么办?

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

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

    • cmd (PID 42)开始
    • cmd (PID 42)运行 foo.bat
    • cmd (PID 42)退出
    • Java喜欢知道该过程是否完成并检查PID 42
  4. 糟糕,该过程已消失,批处理文件已运行。



 类似资料:
  • 问题内容: 我有一个简单的问题。我想运行一个应在构建后运行的bat文件。bat文件采用参数previousVersion和currentVersion(在构建开始之前,这些参数作为“验证字符串参数”输入)。 这是我尝试过的“执行Windows批处理命令” 我得到的错误是cmd无法识别为内部或外部命令可操作程序或批处理文件出口9009 问题答案: 将“ cmd \ k”替换为“ call” “执行W

  • 项目 当我运行代码时得到一些错误。

  • 我在网上搜索了很多关于vs await async,但是在这个特定的使用场景中,我并不真正理解其中的区别。我相信情况很简单。 vs. 其中,是一个异步方法,其中包含一些异步调用,例如使用wait调用db。 问题: 在这种情况下,两者之间有什么区别吗?任何帮助或意见,谢谢!

  • 问题内容: 我的詹金斯装在 bat文件位于 当我从cmd运行此bat文件时,一切正常。但是当我尝试从jenkins执行Image中提到的批处理命令时,Jenkins显示错误为 构建步骤“执行Windows批处理命令”将构建标记为失败 另外,在je​​nkins文件夹中,会自动用工作标题名称创建工作区文件夹。你们能详细解释一下吗 问题答案: Tatkal,您无法执行图片中的命令, 你为什么不尝试 C

  • 我有一个bat文件,它启动了一个程序,并且已经输入了我的用户名和密码,我必须让cmd打开,程序才能运行。我想隐藏cmd窗口,以防止我意外关闭,下面是代码: 我需要把这个藏起来,但是在我想要的时候出现在任务管理器中关闭...谢谢