In addition to manners cited by Caputo, it is possible to use the function ShellExecuteEx
to execute the jar, save to a file and upload it to a TStringList
. Something like this:
function ExecutarComando(Comando: string): TStringList;
var
SE: TShellExecuteInfo;
ExitCode: DWORD;
begin
Result := TStringList.Create;
FillChar(SE, SizeOf(SE), 0);
SE.cbSize := SizeOf(TShellExecuteInfo);
SE.fMask := SEE_MASK_NOCLOSEPROCESS;
SE.Wnd := Application.Handle;
SE.lpFile := 'cmd.exe';
SE.lpParameters := pchar('/C' + Comando + ' > output.txt');
SE.nShow := SW_HIDE;
if ShellExecuteEx(@SE) then begin
repeat
Application.ProcessMessages;
GetExitCodeProcess(SE.hProcess, ExitCode);
until (ExitCode <> STILL_ACTIVE) or Application.Terminated;
Result.LoadFromFile('output.txt');
end else
RaiseLastOSError;
end;
To use:
procedure TForm1.Button1Click(Sender: TObject);
begin
Memo1.Lines := ExecutarComando('java arquivo.jar listar');
end;
The above method is functional, but not ideal, another way more elegant to do this is to create the process with the function CreateProcess
, and redirect the output to a Buffer with the function CreatePipe
, basically.
That page shows an example of how to do this.
function GetDosOutput(CMD: string; Diretorio: string = 'C:\'): string;
var
SA: TSecurityAttributes;
SI: TStartupInfo;
PI: TProcessInformation;
StdOutPipeRead, StdOutPipeWrite: THandle;
Handle, WasOK: Boolean;
Buffer: array[0..255] of AnsiChar;
BytesRead: Cardinal;
begin
Result := '';
SA.nLength := SizeOf(SA);
SA.bInheritHandle := True;
SA.lpSecurityDescriptor := nil;
CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
try
FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);
SI.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
SI.wShowWindow := SW_HIDE;
SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
SI.hStdOutput := StdOutPipeWrite;
SI.hStdError := StdOutPipeWrite;
Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CMD), nil, nil, True,
0, nil, pchar(Diretorio), SI, PI);
CloseHandle(StdOutPipeWrite);
if Handle then
try
repeat
WasOK := ReadFile(StdOutPipeRead, Buffer, 255, BytesRead, nil);
if BytesRead > 0 then begin
Buffer[BytesRead] := #0;
Result := Result + String(Buffer);
end;
until not WasOK or (BytesRead = 0);
WaitForSingleObject(PI.hProcess, INFINITE);
finally
CloseHandle(PI.hThread);
CloseHandle(PI.hProcess);
end;
finally
CloseHandle(StdOutPipeRead);
end;
end;
To use:
procedure TForm1.Button2Click(Sender: TObject);
begin
// O segundo argumento é opcional, por padrão o comando executa em C:\
Memo1.Text := GetDosOutput('java arquivo.jar listar', 'C:\Dir\');
end;
At least until Delphi 7 this was done using the Windows API. If you just want to launch the other application is easy. If you want to wait for him to finish, it’s more boring and if you want to read his exits you have to go to the dark side of the force. Specify your version of Delphi and what you need to get from the other program. You can read this in the meantime: Delphi.about.com/od/windowsshellapi/a/executeprogram.htm
– Caffé
Exactly @Caffé, I want to run and read their outputs and give entries in it too, in the gringo overflow stack told me something about Createprocess and about Pipes but I did not understand very well how it works and if it will work for my case, as for the version of Delphi I have here available to 2009 and XE5
– brunodotcom
In a very simple way, you can use
java seuJar.jar parametros > .\output.txt
and then the console output will be saved in the informed file.– Caputo
The @Caputo is correct if you don’t need to get the outputs whereas they are delivered. Also, I have a code ready that I adapted from an article on the internet that I can’t find anymore. I’ll see if I bring it tomorrow to post here. Now, as for sending entries to a running application the solution can be very complex and depends on a lot of things: do you pass values just by firing the program? (then it would be simple). Do you want to pass values while running the program? What kind of values are and how the program expects to get these values?
– Caffé
So @Caffé, the application that I have it has only 2 commands, list and exit, I would need to open this application by Delphi and the same give these commands and in case of the list I would get the information that it would return.
– brunodotcom
@brunodotcom Managed to solve the problem?
– stderr
@qmechanik Thanks for the answers, I haven’t really had time to implement your idea, but apparently it will. By the time I can deploy I’ll have the answer here.
– brunodotcom