spring boot 使用commons-exec 调用外部exe,并传入参数
需要用java调用外部exe,并传入参数,通过网上查找,可以用commons-exec。 (外部的exe使用python写的,启动的时候,也是可以用cmd命令直接执行的)
1.pom.xml中添加依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-exec</artifactId>
<version>1.3</version>
</dependency>
2.代码中使用
public int exeCommand() throws Exception {
PumpStreamHandler pumpStreamHandler = new PumpStreamHandler();
// 设置超时时间为5min
ExecuteWatchdog watchdog = new ExecuteWatchdog(1000 * 60 * 5);
DefaultExecutor executor = new DefaultExecutor();
int code = -1;
try {
CommandLine commandLine = CommandLine.parse("D:\a\b.exe");
commandLine.addArgument("--configs");
commandLine.addArgument("configs/RSdata/H_48_CHG_SEG.json");
commandLine.addArgument("--phase");
commandLine.addArgument("test");
commandLine.addArgument("--bn_type");
commandLine.addArgument("torchbn");
commandLine.addArgument("--resume");
commandLine.addArgument("D:\a\sensegment_max_performance.pth");
//还有其他参数,就不一一添加了。可以用addArgument()添加单个参数,也可以用addArguments批量添加多个参数
// String[] params = new String [] { "--configs","configs/RSdata/H_48_CHG_SEG.json","--phase","test","--bn_type","torchbn","--resume","D:\a\sensegment_max_performance.pth"};
// CommandLine commandLine = new CommandLine("D:\a\b.exe");
// commandLine.addArguments(params);
executor.setStreamHandler(pumpStreamHandler);
executor.setWatchdog(watchdog);
File f1=new File("D:\a");
executor.setWorkingDirectory(f1);
code = executor.execute(commandLine);
} catch (Exception exception) {
if (watchdog.killedProcess()) {
logger.error("超时了");
}
throw new Exception(exception.toString());
}
return code;
}
3.注意
1.刚开始执行代码里调用普通的ping,是可以成功,但是执行exe,传参失败。
我刚开始以为是参数写的不对,但是我在cmd窗口中执行,是没有问题的,然后我在参数上就一个一个的添加,发现,少个参数可以执行,有返回值,但是没有正确的结果,因为参数传少了,然后我以为是java jdk版本的问题, 我用的是最新的jdk,然后我就用8又试了一次,发现还是同样的问题;然后我就用ProcessBuilder的方法重新试了下,发现还是同样的问题。
2.我开始追踪源码
发现Process的exitValue值是0的时候,表示执行成功,但是我在执行本地exe的时候一直是1,1或者2就是表示失败了。
3.我开始把命令放在cmd文件执行中
因为我的cmd文件放到桌面上也执行失败,但放在对应的文件夹下执行成功。这个时候,我在想是不是java执行的时候,cmd运行的文件夹不对,接下来我终于要找到问题了。
4.设置commons-exec新建进程启动的目录
参数:cmd.exe /D cd D:\a
后来发现我不论怎么切换路径输出的路径都是我java项目启动的路径,我开始跟踪源码
看到了dictory,而且值一直是.,也就是代表着上步中java项目启动的路径我开始大胆猜想会不是这个dictory属性就是设置cmd启动的路径。
于是我找到了executor类的workingDirectory属性
File f1=new File("D:\a");
executor.setWorkingDirectory(f1);
再次执行代码,运行成功了