2

我的 PC 在 Windows7 64 位下运行,我有一个实用程序(.exe,非常旧的 [~WinXP 时代],没有可用的资源),我想从部署到 Jetty 中的 java 代码中调用它。如果我从控制台启动实用程序,我不会收到任何错误。如果我通过简单的 java 包装器启动实用程序:

import java.util.*;
import java.io.*;
public class Wrapper {
    public static void main(String[] args) throws IOException {
        System.out.println(System.getProperty("java.version"));
        Runtime.getRuntime().exec("util.exe -opt1 -opt2");
    }
}

我也没有错误。但是,如果我从 WAR 内部调用此代码(比Runtime.getRuntime().exec("util.exe")复杂一点,因为我需要计算二进制文件的绝对路径),我会收到带有以下消息的 IOException:

CreateProcess 错误=216,此版本的 %1 与您正在运行的 Windows 版本不兼容。检查您计算机的系统信息,看看您是否需要 x86(32 位)或 x64(64 位)版本的程序,然后联系软件发行商

我尝试使用 -d32 选项启动码头,尝试将不同版本的 java(JRE/JDK,均为 6/7,均为 32/64 位)放入 JAVA_HOME 和 PATH,但没有成功。

有没有人遇到过类似的问题?有可能解决它们吗?

[更新] 我附上了一些服务器代码。 CommandLine 和 FileUtils是 Apache Commons 的一部分。ApplicationContextSpring Framework相关。

public class ImageLoader implements ApplicationContextAware {
    private final static String UTIL_EXECUTABLE = "util.exe";
    private final static String TEMP_FILE_PREFIX = "tmpFilePrefix";

    private ApplicationContext applicationContext;
    private File binaryPath;

    @PostConstruct
    public void init() throws Exception {
        if (applicationContext instanceof WebApplicationContext) {
            Resource binaryRoot = applicationContext.getResource(
                    "WEB-INF/classes/executable");
            this.binaryPath = binaryRoot.getFile();
        }
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    /**
     * Download db image from device.
     */
    public byte[] downloadImage(Device device) throws LoaderException {
        try {
            File file = downloadWindows(device);
            return FileUtils.readFileToByteArray(file);
        } catch (Exception ex) {
            throw new LoaderException("Error downloading file: " + ex.getMessage(), ex);
        }
    }

    private File downloadWindows(final Device device) throws Exception {
        File tmpFile = File.createTempFile(TEMP_FILE_PREFIX, null);
        CommandLine command = generateCommand(ActionType.download, tmpFile, device.getTargetIP(), "user", "pass");
        Runtime.getRuntime().exec(command.toString());
        return tmpFile;
    }

    protected CommandLine generateCommand(ActionType actionType, File file, String targetIP, String userName, String userPassword) throws IOException {
        String bin = this.binaryPath.getPath() + "\\" + UTIL_EXECUTABLE; 
        // safe to use \\ because code only runs if WAR deployed under Windows    
        CommandLine commandLine = new CommandLine(bin.replace("\\", "\\\\"));
        commandLine.addArgument(actionType.name());
        commandLine.addArgument(file.getAbsolutePath().replace("\\", "\\\\"));
        commandLine.addArgument(targetIP);
        commandLine.addArgument(userName);
        commandLine.addArgument(userPassword);
        return commandLine;
    }
}

enum ActionType {
    download,
    upload
}
4

1 回答 1

1

对我和我的疏忽感到羞耻。问题实际上出在“其他地方”。WAR 是由 maven 构建的,可执行文件像任何其他资源一样被处理,因此校验和与原始文件相比是不同的。我从过滤中排除了 exe 文件(在 pom.xml 中),它开始正常工作。

于 2014-04-03T06:22:01.753 回答