public class RuntimeExecDemo {
public static void main(String[] args) {
try {
// Windows 路徑需雙反斜杠或正斜杠
String cmd = "C:/Program Files/Microsoft Visual Studio/Common/MSDev98/Bin/MSDEV.EXE";
Process process = Runtime.getRuntime().exec(cmd);
// 可選:等待結束、獲取退出碼
int exitCode = process.waitFor();
System.out.println("進程退出碼: " + exitCode);
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
}
ProcessBuilder pb = new ProcessBuilder("notepad.exe", "readme.txt");
pb.directory(new File("C:/workspace")); // 工作目錄
pb.environment().put("MY_VAR", "value"); // 環境變量
pb.redirectErrorStream(true); // 合併錯誤流到標準輸出
Process process = pb.start();
// 異步讀取輸出流 (防阻塞)
try (BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
int exitCode = process.waitFor();
| 問題 | 原因 | 解決方案 |
|---|---|---|
| 進程掛起/死鎖 | 輸出/錯誤流緩衝區填滿,子進程寫入阻塞 | **必須**在單獨線程中讀取 getInputStream() 和 getErrorStream(),或 redirectErrorStream(true) |
| 路徑含空格失效 | 命令字符串解析錯誤 | 使用 ProcessBuilder 列表形式傳參,或嚴格引用 |
| 中文亂碼 | 系統默認編碼與控制台不一致 | 顯式指定 InputStreamReader(stream, "GBK") 或 StandardCharsets.UTF_8 |
| 權限不足 | 目標程式需管理員權限 | 簽名 JAR、配置 UAC、或使用 JNA/JNI 調用 ShellExecuteEx |
process.waitFor(timeout, TimeUnit.SECONDS) (JDK 8+)。exitCode 判斷成敗,非 0 視為異常。cmd /c、Linux sh -c。避免拼接用戶輸入構造命令 (命令注入風險)。若必須動態參數,使用 ProcessBuilder 列表形式,參數不經 Shell 解析。