Solved

Start commandline-application from Windows-app?

Posted on 2001-09-12
9
121 Views
Last Modified: 2010-04-06
How to start a command-line application (e.g. java)
from a Delphi windows-application?
How to get the output from the DOS-application
back into a Memo?
Do I have to care about/configure the
memory-management of the started application?

Thanks for help,

Gamba

0
Comment
Question by:Gamba
  • 5
  • 4
9 Comments
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Don't know about java. Here is how to start a DOS application and get the output back:

function StartPiped(cmdLine: string; timeout: dword = INFINITE) : string;
var sa     : TSecurityAttributes;
    si     : TStartupInfo;
    pi     : TProcessInformation;
    pr, pw : dword;
    dw1    : dword;
begin
  result := '';
  with sa do begin
    nLength              := sizeOf(sa);
    bInheritHandle       := true;
    lpSecurityDescriptor := nil;
  end;
  CreatePipe(pr, pw, @sa, 0);
  try
    ZeroMemory(@si, sizeOf(si));
    with si do begin
      cb          := sizeOf(si);
      dwFlags     := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
      wShowWindow := SW_HIDE;
      hStdInput   := GetStdHandle(STD_INPUT_HANDLE);
      hStdOutput  := pw;
      hStdError   := pw;
    end;
    if CreateProcess(nil, pchar(cmdLine), nil, nil, true, 0, nil, nil, si, pi) then
      try
        WaitForSingleObject(pi.hProcess, timeout);
        if PeekNamedPipe(pr, nil, 0, nil, @dw1, nil) and (dw1 > 0) then begin
          SetLength(result, dw1);
          if (not ReadFile(pr, pointer(result)^, dw1, dw1, nil)) or (dw1 = 0) then
            result := '';
        end;
      finally
        CloseHandle(pi.hThread);
        CloseHandle(pi.hProcess);
      end;
  finally
    CloseHandle(pr);
    CloseHandle(pw);
  end;
end;

Please note, that this function only gives you the complete output after the DOS program has terminated. You can probably change the code so that you get the output while the DOS program is still running already - if you need that.

You don't care about memory management.

Regards, Madshi.
0
 

Author Comment

by:Gamba
Comment Utility
Thanks, Madshi!
The point are yours.

Would you agree to tell me,how getting the output
while the program still is running (and maybe how
to get the formatted output direct into the memo-component)
for another 50 points?

Thank you,
Gamba
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Getting the output into the memo is easy:

Memo1.Text := StartPiped(...);

Getting the function to already catch output while the program is still running, is a tougher one. I once tried that and was not able to make it run reliably. But I tried quite short, because I didn't really need it, so I wrote the StartPiped function and was satisfied with it.
I saw others posting a function which catches output while the program is still running, but I tried that function and it was not reliable enough, at least not for me. However, I'm quite sure that it is possible to make such a function really reliable, but unfortunately I've not the time to do that (I've so many other things to do). I'm sorry. Perhaps you should wait, maybe another expert has a good function, or you could try to modify my function yourself.

Regards, Madshi.
0
 

Author Comment

by:Gamba
Comment Utility
maybe two points:

1. I tried the function, and it works fine for
   most commands. But one java-call, which should
   start an application, did hang at WaitForSingleObject.
   Do you know about limitations?

2. There is one problem with Memo1.Text:=StartPiped(..);
   some applications return crlf, and others seem
   to return only cr (like java), so formatting
   does not work. Do you know about this?

Gamba



0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 
LVL 20

Accepted Solution

by:
Madshi earned 150 total points
Comment Utility
(1)
Maybe the Java program wants to talk to your main thread or something like that. Try replacing the WaitForSingleObject line with this one:

while WaitForSingleObject(pi.hProcess, 50) = WAIT_TIMEOUT do
  Application.ProcessMessages;

(2)
Okay, then use this:

str := StartPiped(...);
madStrings.ReplaceStr(str, #$D, #$D#$A);
memo1.Text := str;

Or perhaps "Replace(str, #$A, #$D#$A);"?

The unit "madStrings" is part of the free package "madBasic", which you can download from my homepage (including sources).

Regards, Madshi.

www.madshi.net
http://help.madshi.net/Data/StringManipulate.htm#ReplaceStr
0
 

Author Comment

by:Gamba
Comment Utility
Thanks for solving this complicate problem!

Gamba
0
 
LVL 20

Expert Comment

by:Madshi
Comment Utility
Just for my interest: Did (1) and (2) both work?
0
 

Author Comment

by:Gamba
Comment Utility
Sure, for further interest:

I tried (1) and unfortunately it did work, but
not for the java-application.
Then I checked for a C++ - implementation (cause
I also want to implement the function in CBuilder)
and found a class implementation:

http://www.doc.ic.ac.uk/~phjk/OperatingSystemsConcepts/Exercises/Tutorial-02/WebVersion-CreatingProcessesV1.htm

This also did not work, and I think, maybe it is
a problem with DOS/batch-applications, but i could not
find out more details until now.


Gamba
0
 

Author Comment

by:Gamba
Comment Utility
one more thing:
I guess, Windows-applications are stable, I did
not have any problems.
0

Featured Post

Highfive + Dolby Voice = No More Audio Complaints!

Poor audio quality is one of the top reasons people don’t use video conferencing. Get the crispest, clearest audio powered by Dolby Voice in every meeting. Highfive and Dolby Voice deliver the best video conferencing and audio experience for every meeting and every room.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Illustrator's Shape Builder tool will let you combine shapes visually and interactively. This video shows the Mac version, but the tool works the same way in Windows. To follow along with this video, you can draw your own shapes or download the file…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now