spring boot 使用commons-exec 调用外部exe

983 阅读2分钟

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);

再次执行代码,运行成功了