Java 解决 Process 执行命令行命令报【CreateProcess error=2, 系统找不到指定的文件。】错误问题

编程经验分享 2024-07-08 11:35:02 阅读 74

目录

问题

问题代码

解决方案

判断操作系统


问题

使用 Process 执行命令行命令时,报 CreateProcess error=2, 系统找不到指定的文件。但明明指定的文件是存在的。而且这种错误只在 IDEA 中运行会报错,打包后直接 java -jar 运行就能正常运行,不会报错。

问题代码

<code>public class MyTest {

public static void main(String[] args) throws Exception {

Path dirPath = Paths.get("D:\\workspace\\funcproject");

ProcessBuilder pb = new ProcessBuilder();

pb.directory(dirPath.toFile());

pb.command("fn", "version");

Process process = pb.start();

try (BufferedReader reader1 = new BufferedReader(new InputStreamReader(process.getInputStream()));

BufferedReader reader2 = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {

String line;

while ((line = reader1.readLine()) != null) {

System.out.println(line);

}

while ((line = reader2.readLine()) != null) {

System.out.println(line);

}

} catch (IOException e) {

e.printStackTrace();

}

process.waitFor();

}

}

解决方案

以上面的问题代码为例,执行的命令行命令 fn 不是有效的可执行文件,而是由命令行 shell ( cmd.exe) 提供的命令。为了从其他进程运行此命令,必须启动cmd.exe并将参数传递给它。

在 Windows 开发环境下,需要在命令参数前面增加两个参数:"cmd.exe", "/C"

pb.command("cmd.exe", "/C", "fn", "version"); 

在 Linux 开发环境下,则新增两个参数为:"bash", "-c"

pb.command("bash", "-c", "fn", "version"); 

判断操作系统

打包后其实能正常运行,代码其实无需做调整。调试时可以在 IDEA 中将代码先改成可以正常运行的(先传入cmd.exe),然后在提交代码时再重新改回来。不过这样显然很麻烦,直接在通过代码来判断,先获取获取当前操作系统,然后根据不同的操作系统传入不同的 shell 名字。

public class MyTest {

public void execute(String Command) throws Exception {

ProcessBuilder pb = new ProcessBuilder();

List<String> cmd = new ArrayList<>();

String shell = getShellBySystem();

cmd.add(shell);

cmd.add(shell.equals("bash") ? "-c" : "/C");

cmd.addAll(Arrays.asList(command.split(" ")));

pb.command(cmd);

Process process = pb.start();

process.getInputStream();

process.waitFor();

}

private String getShellBySystem() {

String system = System.getProperty("os.name").toLowerCase();

if (system.contains("win")) {

return "cmd.exe";

} else if (system.contains("linux")) {

return "bash";

} else {

throw new RuntimeException(String.format("未知系统 %s", system));

}

}

}



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。