/**
* 执行CMD命令
* cmd /c dir 是执行完dir命令后关闭命令窗口。
* cmd /k dir 是执行完dir命令后不关闭命令窗口。
* cmd /c start dir 会打开一个新窗口后执行dir指令,原窗口会关闭。
* cmd /k start dir 会打开一个新窗口后执行dir指令,原窗口不会关闭。
* @param command cmd命令
* @return 命令执行输出语句
* @throws IOException
* @throws InterruptedException
*/
private static String executeCmd(String command) throws IOException, InterruptedException {
System.out.println("Execute command : " + command);
System.out.println("******************************************************************");
Process process = Runtime.getRuntime().exec(command);
process.waitFor(); //等待子进程完成再往下执行。
//创建bufferedReader
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = null;
StringBuilder build = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
line = new String(line.getBytes("UTF-8"));
System.out.println(line);
build.append(line);
}
bufferedReader.close();
int i = process.exitValue(); //接收执行完毕的返回值
if (i == 0) {
System.out.println("执行完成.");
} else {
System.out.println("执行失败.");
}
System.out.println("******************************************************************");
process.destroy(); //销毁子进程
process = null;
return build.toString();
}
/**
* 判断进程是否存在(tasklist /fi "imagename eq processName")
* tasklist 参数列表:
* /S system 指定连接到的远程系统(IP)。
* /U [domain\]user 指定使用哪个用户执行这个命令。
* /P [password] 为指定的用户指定密码。
* /M [module] 列出调用指定的 DLL 模块的所有进程。如果没有指定模块名,显示每个进程加载的所有模块。
* /SVC 显示每个进程中的服务。
* /V 指定要显示详述信息。
* /FI filter 显示一系列符合筛选器指定的进程。
* /FO format 指定输出格式,有效值: "TABLE"、"LIST"、"CSV"。
* /NH 指定栏标头不应该在输出中显示。 只对 "TABLE" 和 "CSV" 格式有效。
* @param processName 进程名称
* @return 存在true;不存在false
*/
private static boolean findProcess(String processName) {
System.out.println("开始查找进程:" + processName);
System.out.println("******************************************************************");
BufferedReader bufferedReader = null;
try {
//后台运行(不会弹出CMD窗口)
Process process = Runtime.getRuntime().exec("tasklist /fi " + '"' + "imagename eq " + processName +'"');
//等待子进程完成再往下执行。
process.waitFor();
//创建bufferedReader
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
String line = null;
//判断是否存在此进程(读取到的内容是否有进程名)
while ((line = bufferedReader.readLine()) != null) {
if (line.indexOf(processName) != -1) {
line = new String(line.getBytes("UTF-8"));
System.out.println(line);
return true;
}
}
return false;
} catch (Exception ex) {
ex.printStackTrace();
return false;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (Exception ex) {}
}
System.out.println("查找进程结束!");
System.out.println("******************************************************************");
}
}
/**
* 杀死进程
* taskkill 参数列表:
* /S system 指定要连接到的远程系统。
* /U [domain\]user 指定应该在哪个用户上下文执行这个命令。
* /P [password] 为提供的用户上下文指定密码。如果忽略,提示输入。
* /F 指定要强行终止的进程。
* /FI filter 指定筛选进或筛选出查询的的任务。
* /PID process id 指定要终止的进程的PID。
* /IM image name 指定要终止的进程的映像名称。通配符 '*'可用来指定所有映像名。
* /T Tree kill: 终止指定的进程和任何由此启动的子进程。
* @param processName 进程名称
* @throws Exception
*/
private static void killProc(String processName) throws Exception {
System.out.println("关闭应用程序:" + processName);
executeCmd("taskkill /F /IM " + processName);
}
public static void main(String[] args) {
//BAT文件绝对路径
String filePath = "E:\\test.bat";
//CMD命令文本
String command = "cmd.exe /k start "+filePath;
try {
//查找进程是否存在,存在则杀死
if(findProcess("cmd.exe")){
killProc("cmd.exe");
}
if(findProcess("calc.exe")){
killProc("calc.exe");
}
/**************************判断是否支持桌面API**************************/
if (Desktop.isDesktopSupported()) { //支持
Desktop.getDesktop().open(new File(filePath)); //打开bat文件(弹出CMD窗口)
System.out.println("启动计算器中。。。");
} else { //不支持
executeCmd(command); //执行CMD命令
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
运行结果:
test.bat文件内容:start calc.exe