【发布时间】:2014-07-01 11:28:35
【问题描述】:
我有 Delphi 代码,用于从 JAVA_HOME 运行 Java.exe,并带有一组给定的参数。这是通过 CreateProcess() 通过将命令行命令传递给它来实现的。对于一组特定的输入参数,这给了我一个错误,上面写着“无法创建 Java 虚拟机”。我需要通过 PeekNamedPipe() 将其导入 Delphi 代码并将其显示在应用程序中。我怎样才能做到这一点? Delphi 代码如下所示:
begin
securityAttr.nlength := SizeOf(TSecurityAttributes);
securityAttr.binherithandle := true;
securityAttr.lpsecuritydescriptor := nil;
if CreatePipe (readPipe, writePipe, @securityAttr, 0) then
begin
buffer := AllocMem(READ_BUFFER + 1);
FillChar(startInfo, Sizeof(startInfo), #0);
startInfo.cb := SizeOf(startInfo);
startInfo.hStdOutput := writePipe;
startInfo.hStdInput := readPipe;
startInfo.dwFlags := STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
startInfo.wShowWindow := SW_HIDE;
if SearchPath(nil, PChar(consoleApp), '.exe', SizeOf(consoleAppBuf), consoleAppBuf, exeName) = 0 then
raise EInOutError.CreateFmt('Could not find file %s', [consoleApp]);
FmtStr(commandLine, '"%s" %s', [consoleAppBuf, parameters]);
if CreateProcess(nil, PChar(commandLine), nil, nil, true, CREATE_NO_WINDOW, nil, nil, startInfo, processInfo) then
begin
totalBytesRead := 0;
repeat
exitCode := WaitForSingleObject(ProcessInfo.hProcess, 100);
Application.ProcessMessages;
if (PeekNamedPipe(readPipe, @buffer[totalBytesRead],
READ_BUFFER, @bytesRead,
@totalBytesAvail, @bytesLeftThisMessage)) then
begin
if (bytesRead > 0) then
ReadFile(readPipe, buffer[totalBytesRead], bytesRead, bytesRead, nil);
totalBytesRead := totalBytesRead + bytesRead;
end;
until (exitCode <> WAIT_TIMEOUT);
GetExitCodeProcess(ProcessInfo.hProcess, result);
buffer[totalBytesRead]:= #0;
OemToChar(buffer, buffer);
output.Text := output.Text + StrPas(buffer);
FreeMem(buffer);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
CloseHandle(readPipe);
CloseHandle(writePipe);
end
else
RaiseLastWin32Error;
end;
如何读取 java.exe 抛出的错误?
【问题讨论】:
-
为什么把进程的标准输入/输出连接到同一个管道?你想通过这样做来达到什么目的?或者你只是随机尝试使用管道?这段代码有什么作用吗?流程的输出到哪里去了?标准输出还是标准错误?
-
这是一个从delphi函数中运行的sn-p控制台应用程序。它将为命令行参数 createProcess() 并读取进程的结果。该过程的输出进入 PeekNamedPipe 的输入缓冲区。然而,这只发生在 java.exe 成功运行且没有任何错误时。我需要捕获运行 java.exe 时抛出的错误
-
请再次发表评论。为什么将同一管道的两端连接到相同的工艺标准手柄?
-
您正在将子进程的标准输出重定向到子进程的标准输入。次要:您不必轮询管道句柄,它会在数据可用时发出信号。
-
不确定这是如何工作的。我假设创建了一个 ReadPipe 并且 PeekNamedPipe() 是从控制台应用程序输出读取输出。
标签: delphi console-application