Windows 二进制文件在 CMD 上工作但不(总是)在 ProcessBuilder 上工作
Windows Binary working on CMD but not (always) with ProcessBuilder
我开发了一个 C++
应用程序,我想从我的 Java
应用程序中调用它。为此,我使用 ProcessBuilder
:
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
String processOutput = readFromProcess(process);
val exitCode = process.waitFor();
if (exitCode != 0)
{
// Exception
}
return processOutput;
以下是我读取过程输出的方式:
public static String readFromProcess(Process process) throws IOException
{
StringBuilder stringBuilder;
String lineSeparator = lineSeparator();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())))
{
stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null)
{
stringBuilder.append(line);
stringBuilder.append(lineSeparator);
}
}
return stringBuilder.toString().trim();
}
我得到:
exit code -1073741819 (0xC0000005)
这似乎意味着 The application was unable to start correctly
,我什至没有在 EXE
代码的开头得到初始版权控制台打印。
如果我 运行 CMD
上的 EXE
相反,它会 运行 成功,即使我传递了完全相同的参数。为什么会这样?我编译了 Linux
和 Mac OS X
的代码,但它们 运行 通过 Java
和 Terminal
在各自的操作系统上都很好。提到的退出代码 0xC0000005
只出现在 Windows
而不仅仅是在我的电脑上。其他 2 位用户也发现了这个问题。有时 Windows
EXE
仍然会从 Java
运行 尽管这更奇怪。
我使用的C++
编译标志是:
# /MD Causes the application to use the multithread-specific and DLL-specific version of the run-time library:
# https://docs.microsoft.com/en-us/previous-versions/2kzt1wy3(v=vs.140)
# /Ox (Full Optimization): https://docs.microsoft.com/en-us/previous-versions/59a3b321(v=vs.140)
# /GL (Whole Program Optimization): https://docs.microsoft.com/en-us/previous-versions/0zza0de8(v=vs.140)
# /cgthreads (Code Generation Threads): https://docs.microsoft.com/en-us/previous-versions/dn631956(v=vs.140)
# /MP (Build with Multiple Processes): https://docs.microsoft.com/en-us/previous-versions/bb385193(v=vs.140)
# /fp (Specify Floating-Point Behavior): https://docs.microsoft.com/en-us/previous-versions/e7s85ffb(v=vs.140)
# /Gw (Optimize Global Data): https://docs.microsoft.com/en-us/previous-versions/dn305952(v=vs.140)
# /GS (Buffer Security Check): https://docs.microsoft.com/en-us/previous-versions/8dbf701c(v=vs.140)
# /favor (Optimize for Architecture Specifics): https://docs.microsoft.com/en-us/previous-versions/ms173505(v=vs.140)
# /Qpar (Auto-Parallelizer): https://docs.microsoft.com/en-us/previous-versions/hh923900(v=vs.140)
# /EH (Exception Handling Model): https://docs.microsoft.com/en-us/previous-versions/1deeycx5(v=vs.140)
# DNDEBUG: Disable assert macro evaluation
set(OPTIMIZATIONS "/MD /Ox /GL /cgthreads8 /MP8 /fp:fast /Gw /GS- /favor:INTEL64 /Qpar /EHs /EHc- /DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${OPTIMIZATIONS}")
原来传递的参数不一样,因为 Java
将空字符串解释为 Windows
上没有参数。因此,它索引了超出范围的参数数组,并且仍然拒绝打印内存错误发生之前的任何内容,这是不直观的。
我开发了一个 C++
应用程序,我想从我的 Java
应用程序中调用它。为此,我使用 ProcessBuilder
:
ProcessBuilder processBuilder = new ProcessBuilder(command);
processBuilder.redirectErrorStream(true);
Process process = processBuilder.start();
String processOutput = readFromProcess(process);
val exitCode = process.waitFor();
if (exitCode != 0)
{
// Exception
}
return processOutput;
以下是我读取过程输出的方式:
public static String readFromProcess(Process process) throws IOException
{
StringBuilder stringBuilder;
String lineSeparator = lineSeparator();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())))
{
stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null)
{
stringBuilder.append(line);
stringBuilder.append(lineSeparator);
}
}
return stringBuilder.toString().trim();
}
我得到:
exit code -1073741819 (0xC0000005)
这似乎意味着 The application was unable to start correctly
,我什至没有在 EXE
代码的开头得到初始版权控制台打印。
如果我 运行 CMD
上的 EXE
相反,它会 运行 成功,即使我传递了完全相同的参数。为什么会这样?我编译了 Linux
和 Mac OS X
的代码,但它们 运行 通过 Java
和 Terminal
在各自的操作系统上都很好。提到的退出代码 0xC0000005
只出现在 Windows
而不仅仅是在我的电脑上。其他 2 位用户也发现了这个问题。有时 Windows
EXE
仍然会从 Java
运行 尽管这更奇怪。
我使用的C++
编译标志是:
# /MD Causes the application to use the multithread-specific and DLL-specific version of the run-time library:
# https://docs.microsoft.com/en-us/previous-versions/2kzt1wy3(v=vs.140)
# /Ox (Full Optimization): https://docs.microsoft.com/en-us/previous-versions/59a3b321(v=vs.140)
# /GL (Whole Program Optimization): https://docs.microsoft.com/en-us/previous-versions/0zza0de8(v=vs.140)
# /cgthreads (Code Generation Threads): https://docs.microsoft.com/en-us/previous-versions/dn631956(v=vs.140)
# /MP (Build with Multiple Processes): https://docs.microsoft.com/en-us/previous-versions/bb385193(v=vs.140)
# /fp (Specify Floating-Point Behavior): https://docs.microsoft.com/en-us/previous-versions/e7s85ffb(v=vs.140)
# /Gw (Optimize Global Data): https://docs.microsoft.com/en-us/previous-versions/dn305952(v=vs.140)
# /GS (Buffer Security Check): https://docs.microsoft.com/en-us/previous-versions/8dbf701c(v=vs.140)
# /favor (Optimize for Architecture Specifics): https://docs.microsoft.com/en-us/previous-versions/ms173505(v=vs.140)
# /Qpar (Auto-Parallelizer): https://docs.microsoft.com/en-us/previous-versions/hh923900(v=vs.140)
# /EH (Exception Handling Model): https://docs.microsoft.com/en-us/previous-versions/1deeycx5(v=vs.140)
# DNDEBUG: Disable assert macro evaluation
set(OPTIMIZATIONS "/MD /Ox /GL /cgthreads8 /MP8 /fp:fast /Gw /GS- /favor:INTEL64 /Qpar /EHs /EHc- /DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "${OPTIMIZATIONS}")
原来传递的参数不一样,因为 Java
将空字符串解释为 Windows
上没有参数。因此,它索引了超出范围的参数数组,并且仍然拒绝打印内存错误发生之前的任何内容,这是不直观的。