我将其作为一个单独的问题发布的原因是,我已经问过的一个问题得到了正确回答。通过一些研究,我发现我的问题是我所遇到的问题所独有的,因此我决定创建一个新问题。由于它们关系密切,因此请先阅读该问题,然后再继续进行此问题。
运行建议的代码会在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
。
原则上,现在看起来如下所示:
cmd
并指示其运行start foo.bat
并保持打开状态以进行交互式输入(/k
)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)等待…)是的,它仍然在那里。怎么办?
您想要的(以及上述更改将完成的工作)是:
cmd
并指示其foo.bat
在运行命令(/c
)后运行并关闭Java存储进程ID(PID 42),以便以后引用该进程
cmd
(PID 42)开始cmd
(PID 42)运行 foo.bat
cmd
(PID 42)退出糟糕,该过程已消失,批处理文件已运行。
问题内容: 我有一个简单的问题。我想运行一个应在构建后运行的bat文件。bat文件采用参数previousVersion和currentVersion(在构建开始之前,这些参数作为“验证字符串参数”输入)。 这是我尝试过的“执行Windows批处理命令” 我得到的错误是cmd无法识别为内部或外部命令可操作程序或批处理文件出口9009 问题答案: 将“ cmd \ k”替换为“ call” “执行W
项目 当我运行代码时得到一些错误。
我在网上搜索了很多关于vs await async,但是在这个特定的使用场景中,我并不真正理解其中的区别。我相信情况很简单。 vs. 其中,是一个异步方法,其中包含一些异步调用,例如使用wait调用db。 问题: 在这种情况下,两者之间有什么区别吗?任何帮助或意见,谢谢!
问题内容: 我的詹金斯装在 bat文件位于 当我从cmd运行此bat文件时,一切正常。但是当我尝试从jenkins执行Image中提到的批处理命令时,Jenkins显示错误为 构建步骤“执行Windows批处理命令”将构建标记为失败 另外,在jenkins文件夹中,会自动用工作标题名称创建工作区文件夹。你们能详细解释一下吗 问题答案: Tatkal,您无法执行图片中的命令, 你为什么不尝试 C
我有一个bat文件,它启动了一个程序,并且已经输入了我的用户名和密码,我必须让cmd打开,程序才能运行。我想隐藏cmd窗口,以防止我意外关闭,下面是代码: 我需要把这个藏起来,但是在我想要的时候出现在任务管理器中关闭...谢谢