java执行cmd/wmic命令

本文介绍了一个Java工具类ExecuteCmdUtils,通过使用线程并行读取cmd命令的输出流,解决了exe执行时输出过多导致线程阻塞的问题,提高了执行效率。方法包括启动两个线程分别读取标准输出和错误流,并在找到结束标志时中断进程。
摘要由CSDN通过智能技术生成

最新改变:解决执行exe输出太多,线程阻塞。改用线程读取输出流

package org.jeecg.modules.dam.util;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

@Slf4j
public class ExecuteCmdUtils {
	public static Boolean OVER_FLAG = false;
	/**
	 * 执行cmd命令
	 * @param command 命令
	 * @param overFlag 结束标志
	 */
	public static Result<?> executeCmd(String command,String overFlag){
		Runtime runtime = Runtime.getRuntime();
		Process process = null;
		try {
			process = runtime.exec(command);
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			//获取进程的标准输入流
			final InputStream is1 = process.getInputStream();
			//获取进城的错误流
			final InputStream is2 = process.getErrorStream();
			//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
			if(overFlag!=null) {
				new Thread() {

					public void run() {
						BufferedReader br1 = null;
						try {
							br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
						try {
							String line1 = null;
							while ((line1 = br1.readLine()) != null) {
								if (line1 != null){}
								System.out.println(line1);
								if (!"".equals(line1) && line1.contains(overFlag)) {//计算完成标志
									System.out.println("计算成功结束标志!!!");
									OVER_FLAG = !OVER_FLAG;//重置
									interrupt();
									break;
								}
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
						finally{
							try {
								is1.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				}.start();
			}else{
				new Thread() {
					public void run() {
						BufferedReader br1 = null;
						try {
							br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
						try {
							String line1 = null;
							while ((line1 = br1.readLine()) != null) {
								if (line1 != null){}
								System.out.println(line1);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
						finally{
							try {
								is1.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				}.start();
			}
			new Thread() {
				public void  run() {
					BufferedReader br2 = null;
					try {
						br2 = new BufferedReader(new InputStreamReader(is2, "GBK"));
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
					try {
						String line2 = null ;
						while ((line2 = br2.readLine()) !=  null ) {
							if (line2 != null){}
							System.out.println(line2);
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
					finally{
						try {
							is2.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();
			//可能导致进程阻塞,甚至死锁
			int ret = process.waitFor();
			if(overFlag!=null && OVER_FLAG == true){
				OVER_FLAG = !OVER_FLAG;//重置
				System.out.println("读取到结束标志,执行exe计算成功!!!");
				return Result.OK("执行exe计算成功!!!");
			}
			int exitValue = process.exitValue();
			if(exitValue == 0){
				System.out.println("执行exe计算成功!!!");
				return Result.OK("执行exe计算成功!!!");
			}else{
				System.out.println("执行exe计算失败!!!");
				return Result.error("执行exe计算失败!!!");
			}
		}catch (Exception ex){
			ex.printStackTrace();
			try{
				process.getErrorStream().close();
				process.getInputStream().close();
				process.getOutputStream().close();
			}
			catch(Exception ee){
				return Result.error("执行cmd命令错误");
			}
			return Result.error("执行cmd命令错误");
		}
	}
	/**
	 * 执行cmd命令,带日志
	 * @param command 命令
	 * @param overFlag 结束标志
	 */
	public static Result<?> executeCmdWithLog(String command,String overFlag,String type,String filePath){
		//日志文件
		String strDateFormat = "yyyy-MM-dd HH:mm:ss";
		SimpleDateFormat sdf = new SimpleDateFormat(strDateFormat);
		appendFileContent(filePath, "执行exe:"+type+"(开始运行时间:"+sdf.format(new Date())+")\n");
		Runtime runtime = Runtime.getRuntime();
		Process process = null;
		try {
			process = runtime.exec(command);
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			//获取进程的标准输入流
			final InputStream is1 = process.getInputStream();
			//获取进城的错误流
			final InputStream is2 = process.getErrorStream();
			//启动两个线程,一个线程负责读标准输出流,另一个负责读标准错误流
			if(overFlag!=null) {
				new Thread() {

					public void run() {
						BufferedReader br1 = null;
						try {
							br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
						try {
							String line1 = null;
							while ((line1 = br1.readLine()) != null) {
								if (line1 != null){}
								System.out.println(line1);
								if (!"".equals(line1) && line1.contains(overFlag)) {//计算完成标志
									System.out.println("计算成功结束标志!!!");
									OVER_FLAG = !OVER_FLAG;//重置
									interrupt();
									break;
								}
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
						finally{
							try {
								is1.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				}.start();
			}else{
				new Thread() {
					public void run() {
						BufferedReader br1 = null;
						try {
							br1 = new BufferedReader(new InputStreamReader(is1, "GBK"));
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
						try {
							String line1 = null;
							while ((line1 = br1.readLine()) != null) {
								if (line1 != null){}
								System.out.println(line1);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
						finally{
							try {
								is1.close();
							} catch (IOException e) {
								e.printStackTrace();
							}
						}
					}
				}.start();
			}
			new Thread() {
				public void  run() {
					BufferedReader br2 = null;
					try {
						br2 = new BufferedReader(new InputStreamReader(is2, "GBK"));
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
					try {
						String line2 = null ;
						while ((line2 = br2.readLine()) !=  null ) {
							if (line2 != null){}
							System.out.println(line2);
							appendFileContent(filePath, "执行exe:"+type+"报错:"+line2+"\n");
						}
					} catch (IOException e) {
						e.printStackTrace();
					}
					finally{
						try {
							is2.close();
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			}.start();
			//可能导致进程阻塞,甚至死锁
			int ret = process.waitFor();
			appendFileContent(filePath, "执行exe:"+type+"(结束运行时间:"+sdf.format(new Date())+")");
			if(overFlag!=null && OVER_FLAG == true){
				OVER_FLAG = !OVER_FLAG;//重置
				System.out.println("读取到结束标志,计算成功!!!");
				return Result.OK("计算成功!!!");
			}
			int exitValue = process.exitValue();
			if(exitValue == 0){
				appendFileContent(filePath, "执行exe"+type+"计算成功!!!\n");
				return Result.OK(type+"执行exe计算成功!!!");
			}else{
				appendFileContent(filePath, "执行exe"+type+"计算失败!!!\n");
				return Result.error(type+"执行exe计算失败!!!");
			}
		}catch (Exception ex){
			ex.printStackTrace();
			try{
				process.getErrorStream().close();
				process.getInputStream().close();
				process.getOutputStream().close();
			}
			catch(Exception ee){
				appendFileContent(filePath, "执行exe"+type+"计算失败!!!执行cmd命令关闭流异常\n");
				return Result.error(type+"执行exe计算失败!!!关闭流异常");
			}
			appendFileContent(filePath, "执行exe"+type+"计算失败!!!执行cmd命令异常\n");
			return Result.error(type+"执行exe计算失败!!!执行cmd命令异常");
		}
	}
	/**
	 * 追加文件内容:使用FileWriter
	 * @param filePath
	 * @param content
	 */
	public static void appendFileContent(String filePath, String content) {
		try {
			//打开一个写文件器,构造函数中的第二个参数true表示以追加形式写文件
			FileWriter writer = new FileWriter(filePath, true);
			writer.write(content);
			writer.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * 将生成文件、执行文件路径处理为cmd执行命令
	 * cmd /c D: & cd dam\\1424996459568680961\\dam_base\\front\\grid\\3\\ & 5heat_2015.exe
	 * @param generateDamBasePath 生成文件路径 D:\dam\
	 * @param path 执行文件路径 1424996459568680961\dam_base\after\3\STRESS_S3_EXTRACT.OUT
	 */
	public static String getCommand(String generateDamBasePath,String path){
		//文件路径处理为命令
		String[] split = generateDamBasePath.split(":");
		int i = path.lastIndexOf(File.separator);
		String cmd1 = path.substring(0,i);
		String cmd2 = path.substring(i+1);
		StringBuffer sb = new StringBuffer("cmd /c ");//cmd窗口
		sb.append(split[0]);//切换盘符
		sb.append(": & cd ");
		sb.append(split[1]+cmd1);//进入该目录下
		sb.append(" & ");
		sb.append(cmd2);//执行exe
		String command = sb.toString();
		System.out.println(command);
		return command;
	}

	/**
	 * 将生成文件、执行文件路径处理为wmic执行命令
	 * "cmd /c wmic process where \"Name='change-matXYZ.exe' and ExecutablePath like 'E:\\\\dam\\\\dam_base1\\\\dam_base\\\\front\\\\grid\\\\9ceshi111\\\\%'\" get ProcessId"
	 * @param generateDamBasePath 生成文件路径 E:\dam\
	 * @param path 执行文件路径 dam_base\front\grid\9ceshi111\change-matXYZ.exe
	 */
	public static String getWmicCommand(String generateDamBasePath,String path){
		//文件路径处理为命令
		int i = path.lastIndexOf(File.separator);
		String cmd1 = path.substring(0,i).replace("\\","\\\\");
		String cmd2 = path.substring(i+1);
		StringBuffer sb = new StringBuffer("cmd /c wmic process where \"Name='");//cmd\wmic窗口
		sb.append(cmd2);
		sb.append("' and ExecutablePath like '");
		sb.append(generateDamBasePath.replace("\\","\\\\"));
		sb.append(cmd1);
		sb.append("\\\\%'\" get ProcessId");
		String command = sb.toString();
		System.out.println(command);
		return command;
	}
	/**
	 * 执行命令wmic查询进程pid
	 * @param command
	 */
	public static Result<?> getProcessIdByExecutablePathAndName(String command){
		String line = null;
		BufferedReader br = null;
		BufferedReader brError = null;
		try {
			Process process = Runtime.getRuntime().exec(command);
			br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
			while ((line = br.readLine()) != null) {
				if (!"".equals(line) && !"ProcessId  ".equals(line)) {
					System.out.println(line);
					Integer processId = Integer.valueOf(line.trim());
					return Result.OK(processId);
				}
			}
			brError = new BufferedReader(new InputStreamReader(process.getErrorStream(),"GBK"));
			while ((line = brError.readLine()) != null){
				if (!"".equals(line)) {
					System.out.println(line);
					return Result.error(line);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("执行命令wmic查询进程pid报错");
		} finally {
			if(br != null){
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
					return Result.error("执行命令wmic查询进程pid关闭流报错");
				}
			}
			if(brError != null){
				try {
					brError.close();
				} catch (IOException e) {
					e.printStackTrace();
					return Result.error("执行命令wmic查询进程pid关闭流报错");
				}
			}
		}
		return Result.error("执行命令wmic查询进程pid报错");
	}
	/**
	 * 根据进程pid杀死进程
	 * @param processId 进程pid
	 */
	public static Result<?> killProcessById(String processId){
		String command = "cmd /c taskkill /f /pid "+processId;
		String line = null;
		BufferedReader br = null;
		BufferedReader brError = null;
		try {
			Process process = Runtime.getRuntime().exec(command);
			br = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));
			while ((line = br.readLine()) != null){
				if (!"".equals(line)) {
					System.out.println(line);
					return Result.OK(line);
				}
			}
			brError = new BufferedReader(new InputStreamReader(process.getErrorStream(),"GBK"));
			while ((line = brError.readLine()) != null){
				if (!"".equals(line)) {
					System.out.println(line);
					return Result.error(line);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			return Result.error("根据进程pid杀死进程报错");
		} finally {
			if(br != null){
				try {
					br.close();
				} catch (IOException e) {
					e.printStackTrace();
					return Result.error("根据进程pid杀死进程关闭流报错");
				}
			}
			if(brError != null){
				try {
					brError.close();
				} catch (IOException e) {
					e.printStackTrace();
					return Result.error("根据进程pid杀死进程关闭流报错");
				}
			}
		}
		return Result.error("根据进程pid杀死进程报错");
	}

	/**
	 * 杀死进程
	 * @param generateDamBasePath 生成文件路径
	 * @param path 执行文件路径
	 * @return
	 */
	public static Result<?> killProcessByExecutablePathAndName(String generateDamBasePath,String path,String type){
		String wmicCommand = getWmicCommand(generateDamBasePath, path);
		Result<?> processIdByExecutablePathAndName = getProcessIdByExecutablePathAndName(wmicCommand);
		if(processIdByExecutablePathAndName.isSuccess()){
			Result<?> killProcessById = killProcessById(processIdByExecutablePathAndName.getResult().toString());
			if(killProcessById.isSuccess()){
				return Result.OK(type+"中止任务成功!!!");
			}else{
				return Result.error(type+"中止任务失败!!!根据进程pid杀死进程报错:"+killProcessById.getMessage());
			}
		}else{
			return Result.error(type+"中止任务失败!!!执行命令wmic查询进程pid报错:"+processIdByExecutablePathAndName.getMessage());
		}
	}
	/**
	 * 杀死进程,带日志
	 * @param generateDamBasePath 生成文件路径
	 * @param path 执行文件路径
	 * @return
	 */
	public static Result<?> killProcessByExecutablePathAndNameWithLog(String generateDamBasePath,String path){
		String wmicCommand = getWmicCommand(generateDamBasePath, path);
		Result<?> processIdByExecutablePathAndName = getProcessIdByExecutablePathAndName(wmicCommand);
		if(processIdByExecutablePathAndName.isSuccess()){
			Result<?> killProcessById = killProcessById(processIdByExecutablePathAndName.getResult().toString());
			if(killProcessById.isSuccess()){
				return Result.OK(killProcessById.getResult());
			}else{
				return Result.error("根据进程pid杀死进程报错:"+killProcessById.getMessage());
			}
		}else{
			return Result.error("执行命令wmic查询进程pid报错:"+processIdByExecutablePathAndName.getMessage());
		}
	}
	public static void main(String [] args) {
		//============================测试杀死进程=========================================
//		Result<?> killProcessByExecutablePathAndName = killProcessByExecutablePathAndName("E:\\dam\\", "dam_base1\\dam_base\\front\\grid\\9ceshi111\\change-matXYZ.exe");
//		System.out.println(killProcessByExecutablePathAndName);
		//============================测试pid杀死进程=========================================
		//		Result<?> killProcessById = killProcessById("3712");
		//		System.out.println(killProcessById);
		//============================测试获取exePid/执行wmic命令=============================
		//		String wmicCommand = getWmicCommand("E:\\dam\\", "dam_base1\\dam_base\\front\\grid\\9ceshi111\\change-matXYZ.exe");
		//		Result<?> processIdByExecutablePathAndName = getProcessIdByExecutablePathAndName(wmicCommand);
		// 		System.out.println(processIdByExecutablePathAndName);
		//============================测试执行exe文件=========================================
//		Result<?> executeCmd= executeCmd("cmd /c D: & cd \\dam\\d61222c4459e4b1dac5d54bc9c2e133f\\dam_base\\cloud & saptis7.5_6_ac_2_20200701.exe","finished !!!");
//		      Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam & saptis7.5_6_ac_2_20200701.exe","finished !!!" );
//		executeCmdNew("cmd /c E: & cd \\dam\\a25de1e0f6ac4519b253d1732feb7bab & saptis7.5_6_ac_2_20200701.exe","finished !!!" );
//		Result<?> executeCmd= executeCmd("cmd /c D: & cd \\dam\\0e4512053a5c4f208110f83bb964d422\\dam_base\\after\\cloud_chart & GIDRESULT7.1.exe",null);

		Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\dam_base1\\dam_base\\after\\1ceshi111 & Temp_Extract_7.3.exe","FINISHED AT 540");
		//      Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\4 & add_crack.exe","thicken jelm finished!");
		//      Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\5 & sanre.exe","PROGRAM STOP NORMALLY !");
		//      Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\6 & yueshu.exe",null);
		//		Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\6 & yueshu.exe",null);
		//		Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\cs\\7 & pipe_change.exe",null);
		//      Result<?> executeCmd = executeCmd("cmd /c D: & cd \\dam\\1427505697733971970\\dam_base\\front\\grid\\3 & automesh2015.exe");
		//		Result<?> executeCmd = executeCmd("cmd /c E: & cd \\dam\\dam_base1\\dam_base\\front\\grid\\999 & change-matXYZ.exe",null);
		//		Result<?> executeCmd= executeCmd("cmd /c E: & cd \\dam\\dam_base1\\dam_base\\after\\3ceshi & STRESS_Extract_7.3_FAC.exe",null);
		//		String command = getCommand("E:\\dam\\", "dam_base1\\dam_base\\after\\3ceshi111\\STRESS_Extract_7.3_FAC.exe");
		//		Result<?> executeCmd = executeCmd(command,null);
		System.out.println(executeCmd);
		System.out.println("1111");
		System.out.println("2222");
	}

}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值