Recent

Author Topic: TProcess Java program  (Read 7519 times)

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
TProcess Java program
« on: August 10, 2015, 09:23:46 pm »
I'm trying to find a way to run a java program through TProcess.

I found an example here:  http://wiki.freepascal.org/Executing_External_Programs#Reading_large_output

But if I change the dir to anything else, I just get the Invalid command, please fix the IFDEFS. message.

I've tried mucking with it, but no success.

I can't even get java -version to run and return output.

If someone could help me with just java -version that would be a lot of help

derek.john.evans

  • Guest
Re: TProcess Java program
« Reply #1 on: August 10, 2015, 10:40:01 pm »
Here is some code Im working on for my app. Im running GCC via TProcess and displaying output in a TSynEdit control.

Code: Pascal  [Select][+][-]
  1. function StreamReadChunk(const AStream: TStream): String;
  2. var
  3.   LBuffer: array[byte] of Char;
  4. begin
  5.   LBuffer[0] := #0;
  6.   SetString(Result, LBuffer, AStream.Read(LBuffer, SizeOf(LBuffer)));
  7. end;
  8.  
  9. // **EDIT** Added BeginUpdate/EndUpdate.
  10. procedure StringsWrite(const AStrings: TStrings; const ALine: String);
  11. var
  12.   LLastLine: String;
  13. begin
  14.   AStrings.BeginUpdate;
  15.   try
  16.     if AStrings.Count = 0 then
  17.     begin
  18.       LLastLine := EmptyStr;
  19.     end else begin
  20.       LLastLine := AStrings[AStrings.Count - 1];
  21.       AStrings.Delete(AStrings.Count - 1);
  22.     end;
  23.     AStrings.AddText(LLastLine + ALine + LineEnding);
  24.   finally
  25.     AStrings.EndUpdate;
  26.   end;
  27. end;
  28.  
  29. procedure SynEditWrite(const ASynEdit: TSynEdit; const ALine: String);
  30. begin
  31.   StringsWrite(ASynEdit.Lines, ALine);
  32.   while ASynEdit.Lines.Count > 500 do
  33.   begin
  34.     ASynEdit.Lines.Delete(0);
  35.   end;
  36.   ASynEdit.CaretY := MaxInt;
  37.   Application.ProcessMessages;
  38. end;
  39.  
  40. procedure ProcessExecute(const AProcess: TProcess; const ASynEdit: TSynEdit);
  41. begin
  42.   with AProcess do
  43.   begin
  44.     Options := Options + [poUsePipes, poStderrToOutPut];
  45.     PipeBufferSize := 1024;
  46.     ShowWindow := swoHIDE;
  47.     Execute;
  48.     while Running do
  49.     begin
  50.       while Running and (Output.NumBytesAvailable = 0) do
  51.       begin
  52.         Sleep(400);
  53.       end;
  54.       SynEditWrite(ASynEdit, StreamReadChunk(Output));
  55.     end;
  56.     repeat
  57.       SynEditWrite(ASynEdit, StreamReadChunk(Output));
  58.     until Output.NumBytesAvailable = 0;
  59.   end;
  60. end;  
  61.  

I tested it with this code:

Code: Pascal  [Select][+][-]
  1.   for LIndex := 1 to 10 do
  2.   begin
  3.     Process1.Executable := 'java';
  4.     Process1.Parameters.Text := '-version';
  5.     ProcessExecute(Process1, SynEdit1);
  6.     Process1.Executable := 'gcc';
  7.     Process1.Parameters.Text := '--h';
  8.     ProcessExecute(Process1, SynEdit1);
  9.   end;  
  10.  
« Last Edit: October 02, 2015, 03:28:06 am by Geepster »

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: TProcess Java program
« Reply #2 on: August 10, 2015, 10:55:40 pm »
It is hard to guess what goes wrong. And example I could give here is also in the fact. Why don't you show some code?

Don't forget to specify the path to the java executable

derek.john.evans

  • Guest
Re: TProcess Java program
« Reply #3 on: August 10, 2015, 11:11:16 pm »
Ha, I get it. You see the string 'invalid command, please fix the IFDEFS.'

That example looks all hacked up. It looks like someone put that message there to make sure the command was set correctly for different platforms. Then, someone else took it out because CommandLine is deprecated. Which is fine, but somehow that string is still ending up being used for something.

I'd remove the var OurCommand, and let the compiler find the issue.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #4 on: August 10, 2015, 11:49:07 pm »
derek, when I try your code, I get an external SIGSEGV

I'm on Windows btw, not sure that matters.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #5 on: August 10, 2015, 11:53:39 pm »
Bah, forgot to initialize the process.

With that done, I'm now getting output!

It's weird output, but output nonetheless!

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #6 on: August 11, 2015, 12:03:00 am »
If I do:
Process1.Executable := 'java';
Process1.Parameters.Text := '-version';

I get no output to SynEdit

If I do:
Process1.Executable := 'cmd.exe';
Process1.Parameters.Text := 'java -version';

I get a console window that never goes away, and locks everything up, but I do get console output:
Microsoft Windows [Version 6.1.7601]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.

C:\someFolder>

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #7 on: August 11, 2015, 12:11:19 am »
Even weirder, GCC help does give output, but Java does not...?

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #8 on: August 11, 2015, 12:14:08 am »
The plot thickens.

I'm getting some Java output now, but... I'm getting:

Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'
has value '1.8', but '1.7' is required.
Error: could not find java.dll
Error: Could not find Java SE Runtime Environment.
.Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'
has value '1.8', but '1.7' is required.
Error: could not find java.dll
Error: Could not find Java SE Runtime Environment.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #9 on: August 11, 2015, 12:20:03 am »
Ok, I'm well aware that I'm rambling like a madman now.

But I'm getting Java output   :)

I had to enter the complete path to a java binary, I could not use just 'java' for the reason above.

Not very portable, but I might have  away around that.

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #10 on: August 11, 2015, 12:23:17 am »
And it works, I'm now able to launch an instance of Jetty on demand     :D

You guys rock, without this thread there's no way I would have gotten this far.

On to the next problem, when I hit that button, the whole thing locks up.

I get the output, but it locks up the entire GUI, any simple way to fix that?

derek.john.evans

  • Guest
Re: TProcess Java program
« Reply #11 on: August 11, 2015, 12:55:27 am »
Eck. Try TAsyncProcess

Comment out some lines from ProcessExecute.

Code: [Select]
procedure ProcessExecute(const AProcess: TProcess; const ASynEdit: TSynEdit);
begin
  with AProcess do
  begin
    Options := Options + [poUsePipes, poStderrToOutPut];
    PipeBufferSize := 1024;
    ShowWindow := swoHIDE;
    Execute;
    (* <<<<<< REMOVE THE OLD streaming code.
    while Running do
    begin
      while Running and (Output.NumBytesAvailable = 0) do
      begin
        Sleep(400);
      end;
      SynEditWrite(ASynEdit, StreamReadChunk(Output));
    end;
    repeat
      SynEditWrite(ASynEdit, StreamReadChunk(Output));
    until Output.NumBytesAvailable = 0;
    *) <<< END COMMENT
  end;
end;

Add a OnReadData event to TAsyncProcess.
Code: [Select]
procedure TForm1.AsyncProcess1ReadData(Sender: TObject);
begin
  repeat
    SynEditWrite(SynEdit1, StreamReadChunk(AsyncProcess1.Output));
  until AsyncProcess1.Output.NumBytesAvailable = 0;
end;

But, you still can only run one process at a time, so you need to make sure you check Running before calling Execute again:

Code: [Select]
  if not AsyncProcess1.Running then
  begin
    AsyncProcess1.Executable := 'gcc';
    AsyncProcess1.Parameters.Text := '--h';
    ProcessExecute(AsyncProcess1, SynEdit1);
  end;   


Bad news is, I now cant get java running. Gcc, yes

Nicola Gorlandi

  • Full Member
  • ***
  • Posts: 132
Re: TProcess Java program
« Reply #12 on: August 11, 2015, 06:33:44 am »
You can use this component
http://maxxdelphisite.free.fr/doscmd.htm
is for Delphi but it should run always on Lazarur (for me on windows it works)

Trenatos

  • Hero Member
  • *****
  • Posts: 535
    • MarcusFernstrom.com
Re: TProcess Java program
« Reply #13 on: August 11, 2015, 02:49:57 pm »
I have it working and launching Java software, next step is to see if I can make it handle multiple processes and how to thread things so it doesn't lock up the GUI

 

TinyPortal © 2005-2018