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 權限這個問題也沒有  猜測 上記 獲取權限的代碼 造成了閃屏 調查中... 有知道的請告知 🙏

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM