Run a java Jar from Delphi

4

I would like to know if there is a way to run a jar through Delphi and give commands to it as if it were a command line.

The truth is that I have a java application that no longer has access to the code and it is limited to two commands via console, I would like to create a delphi application that could by a graphical interface control this jar and give commands to they would then instead of typing user commands, it would click on buttons and delphi would do the rest.

Is there any way to do this?

    
asked by anonymous 13.04.2015 / 13:47

2 answers

5

Assuming your jar application if calling myApp.jar you can do as follows

In Delphi you run the command with WinExec for example, or ShellExecute

WinExec('java c:\path\para\meuApp.jar listar >> .\resultadoLista.txt', SW_HIDE);

or

ShellExecute(handle,'open',PChar('java'), 
  'c:\path\para\meuApp.jar listar >> .\resultadoLista.txt','',SW_HIDE)

Then, in delphi you can load the result using a memo or stringlist, for example:

StringList.LoadFromFile('.\resultadoLista.txt')
    
14.04.2015 / 22:17
4

In addition to quoted by Caputo modes, you can use the ShellExecuteEx to run the jar , save to a file and load it into a TStringList . Something similar to 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 elegant way to do this is to create the process with the CreateProcess ", and redirect the output to a Buffer with the CreatePipe ", basically.

This 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;
    
15.04.2015 / 07:40