【问题标题】:Is there any other way to run .exe from Java?有没有其他方法可以从 Java 运行 .exe?
【发布时间】:2014-04-01 20:28:11
【问题描述】:

主要问题是我无法通过 Java 运行我的 c++ 逻辑; 我是否正确创建了子流程?

谢谢大家; - - 更新! ---

所以我写了这些来测试以最纯粹的方式打开 .exe 的能力; Eclipse 可以看到文件/不会抱怨它不存在;使用 Eclipse 中的运行按钮运行:

java文件:

import java.io.*;

public class Runs_A_Exe {
   public static void main( String[] args ){
      try {
         ProcessBuilder pb = new ProcessBuilder( "M:\\aaa\\bbb\\ccc\\ddd\\eee\\workspace\\Runs Simple Exe\\src\\executables\\a.exe" );
         Process p = pb.start();

         InputStream is = p.getInputStream();
         InputStreamReader isr = new InputStreamReader( is );
         BufferedReader br = new BufferedReader( isr );
         System.out.println( br.readLine() );
      }

      catch ( Exception e ) {
         System.out.println( e );
      }
   }
}

c++ 文件:

#include <iostream>

int main( void ) {
   std::cout << "Hey!" << std::endl;
}

输出:

空

【问题讨论】:

  • 如果您在子进程生成空白文件时遇到问题,请询问 那个 问题,而不是寻找另一种从 Java 调用代码的方法。可能错误出在您的 C++ 代码中(例如,在没有附加终端的情况下运行时)。
  • @Greg 但它使用命令行工作
  • 是的,你说过。但是仍然有可能错误地编写程序,使其在命令行中运行,但在从另一个进程调用时却无法运行。
  • 或者可能有其他环境事物(命令路径、动态链接路径、导出的变量、权限)会改变命令行应用程序的调用方式。
  • 如果添加 p.waitFor() 等待子进程完成,可以从中获取返回值。就我而言,它返回 -1073741515,这显然意味着“应用程序未能正确初始化”。 stackoverflow.com/questions/12534659/…

标签: java c++ gui-design


【解决方案1】:

您是否使用正确的参数调用它? C++ 是否有正确的工作目录? Java 是否正确解析标准输出?如果你只在 C++ 中做一个 hello world,你能在 Java 中看到它吗?

我建议从头开始,让它与最简单的 C++ 程序一起工作,然后慢慢复杂化 C++(回到你的逻辑中)

  • 首先从 java 调用一个 hello world,并确保在 Java 中正确读取输出
  • 然后添加几个参数,确保在java中正确读取输出,
  • 然后添加一点逻辑,确保从 Java 中正确读取输出。

并确保 C++始终与 Java 一起正常工作。如果可以的话,编写自动化测试:)


发生的情况是,您从一开始就犯下了没有端到端集成构建应用程序的大罪。你感受到的痛苦是你在为你的罪行赎罪:P。

我当然是在开玩笑,但说真的,下一次,我建议您尽快集成 C++!它的那些集成点始终是任何软件中的问题根源(我知道)。尽早解决它们是确保您以后可以专注于逻辑的好方法。如果我可以建议阅读,请查看Growing object oriented software guided by test,这是对这种方法的一个很好的演示。

【讨论】:

  • 刚刚用一个简单的 hello.cpp 测试了它:没有参数;绝对目录/Eclipse 没有抱怨找不到文件;我让上面的代码为我处理标准输出,到目前为止还没有被认为是错误的......而且 hello.cpp 仍然什么都不做......
  • 奇怪,请先尝试调用系统级 exe,例如 dir。也许 Java 没有抱怨,但仍然无法正常工作。使用waitFor 检查返回码。是0吗?更改 C++,在 main 末尾添加 return 1。它会改变 Java 中 waitFor 的值吗?如果不是,您可能不会调用正确的流程。在创建进程之前执行pb.redirectErrorStream(true);。是否出现错误行?
【解决方案2】:

ProcessBuilder 创建的进程有标准输入、输出和错误流,如果你不写入它的输入流或从它的输出流中读取,它就会挂起。有关详细信息,请参阅以下问题:

Why does process hang if the parent does not consume stdout/stderr in Java?

Java ProcessBuilder: Resultant Process Hangs

也可能因为运行它的用户没有启动它所需的权限,或者因为某些 DLL 无法加载,或者可能是其他原因,所以该进程永远不会启动。

Unable to use taskkill.exe from a Java process

我已经创建了您的程序的修改版本。当我从命令行运行它时,它能够执行 exe 文件,但是当我从 Eclipse 项目中执行相同操作时,该进程返回退出代码 -1073741515,根据上面的问题,这意味着“应用程序未能正确初始化。”我认为您需要调查 Eclipse 调用 java 以运行您的 exe 的环境(它在哪个用户下运行,PATH 的设置方式等),以及 exe 的所有依赖项是否可用(它是什么 DLL)依赖)来确定为什么它没有成功运行。

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;

public class Runs_An_Exe {
    public static void main(String[] args) throws Exception {
        ProcessBuilder pb = new ProcessBuilder("c:/cygwin/tmp/a.exe");
        pb.redirectErrorStream(true); // redirect stderr to stdin
        Process p = pb.start();

        final StringWriter writer = new StringWriter();
        final InputStreamReader isr = new InputStreamReader(p.getInputStream());
        // capture all output from the process
        new Thread(new Runnable() {
            @Override public void run() {
                readAll(isr, writer);
            }
        }).start();
        // wait for it to finish, and display the exit code
        int result = p.waitFor();
        System.out.println("result: " + result);
        // display any output from the process
        System.out.println(writer.toString());
    }

    private static void readAll(Reader reader, Writer writer) {
        try {
            char[] buffer = new char[8192];
            int n = 0;
            while (-1 != (n = reader.read(buffer))) {
                writer.write(buffer, 0, n);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

(我使用的 a.exe 是在问题中使用 32 位 Cygwin 下的 g++ 4.8.2 从您的 C++ 源代码编译而来的。)

【讨论】:

    猜你喜欢
    • 2022-01-23
    • 1970-01-01
    • 2020-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-31
    • 2021-09-06
    • 1970-01-01
    相关资源
    最近更新 更多