Java 执行CMD/DOS
最近在写一个自己的邮箱服务器里用到
监视及起/停 windows 中的服务,调查发现还是得用dos来做这些事情
说一下遭遇战的过程
首先是java里如何执行DOS命令,查到下记函数
Runtime.getRuntime().exec()
(到这你可以试着启动个 记事本 计算器的了Runtime.getRuntime().(“notepad”); Runtime.getRuntime().(“calc”); )
然后就是准备dos命令
服务启动 sc start “服务名”
服务停止 sc start “服务名”
服务状态 sc query “服务名”
(引号必须)
然后是返回值的问题了 起/停 的命令执行后是有返回值的
还没发现比较好的对应方案 现在基本上就是把原本打印在 cmd框里的一行行输出出来自己判断
- 1 private Map<String, String> executeCmd(String cmd) {
- 2 Runtime rt = Runtime.getRuntime(); // 运行时系统获取
- 3 Map<String, String> lineMap = new HashMap<String, String>();//存放返回值
- 4 try {
- 5 Process proc = rt.exec(cmd);// 执行命令
- 6 InputStream stderr = proc.getInputStream();//执行结果 得到进程的标准输出信息流
- 7 InputStreamReader isr = new InputStreamReader(stderr);//将字节流转化成字符流
- 8 BufferedReader br = new BufferedReader(isr);//将字符流以缓存的形式一行一行输出
- 9 String line = null;
- 10 while ((line = br.readLine()) != null) {
- 11 if (!StringUtils.isEmpty(line)) {
- 12 String[] strLine = line.split(":");
- 13 if(strLine.length>=2) {
- 14 lineMap.put(strLine[0].trim(), strLine[1].trim());
- 15 }
- 16
- 17 }
- 18 }
- 19 br.close();
- 20 isr.close();
- 21 stderr.close();
- 22 } catch (IOException e) {
- 23 e.printStackTrace();
- 24 }
- 25 return lineMap;
- 26 }
ps: L11-17 根据不同的命令的执行结果不同 相应改变的 我这里得到的是 xx : yy 这样的所以这样处理
接下来就是 如是 bat 文件 怎么对处
同样的方法 把命令换成你的bat路径就好了 ,这个就不多说了想说一个关于权限的问题
bat文件的话 如果权限不够 通常会邮件bat文件以管理员身份运行 会这样的处理
但java里怎么处理?如下
- 1 @echo off
- 2 mode con lines=30 cols=60
- 3 %1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
- 4 cd /d "%~dp0"
- 5 rem
之后再加上你要写的bat命令就好了
现在想想突然感觉很可怕有 admin 权限 也可以自己写cmd 创建 shell 执行 …
还有一个就是 看当网上说 因执行命令过多或者执行内容过多 会造成Runtime阻塞问题,基本解决方案是多线程处理
就是把子进程的输出流(getInputStream)和错误流(getOutputStream)分给两个线程来做处理 如下
- public class StreamManage extends Thread {
- private final Logger logger = LoggerFactory.getLogger(this.getClass());
- InputStream inputStream;
- String type;
- public StreamManage(InputStream inputStream,String type) {
- this.inputStream = inputStream;
- this.type = type;
- }
- public void run () {
- InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
- BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
- String line = null;
- try {
- while((line = bufferedReader.readLine()) !=null ) {
- if(type.equals("Error")) {
- logger.error(line);
- }else {
- logger.debug(line);
- }
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
这里应该没什么要说的就是把把输出流穿过来做输出处理,然后调用的地方
L8,9
- 1 private void startMailServer() {
- 2 String cmd = "sc start \"James 2.3.2.1\"";// dos 命令
- 3 Runtime rt = Runtime.getRuntime(); // 运行时系统获取
- 4 try {
- 5 // Process proc = rt.exec(cmd);// 执行命令
- 6 File filePath = new File("src\\main\\resources\\static\\bat\\runStart.bat");
- 7 Process proc = rt.exec(filePath.toString());
- 8 StreamManage errorStream = new StreamManage(proc.getErrorStream(), "Error");
- 9 StreamManage outputStream = new StreamManage(proc.getInputStream(), "Output");
- 10 errorStream.start();
- 11 outputStream.start();
- 12 } catch (IOException e) {
- 13 e.printStackTrace();
- 14 }
- 15 }
基本上就这些
最后说一个残留问题
就是 cmd窗口 闪屏的问题 如果执行的的是 命令 这个问题不存在 如果是 bat 不是要获取 admin 权限这个问题也没有 猜测 上记 获取权限的代码 造成了闪屏 调查中… 有知道的请告知