Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7193481
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T20:10:44+00:00 2026-05-28T20:10:44+00:00

I have a commandline application coded in delphi that I need to call from

  • 0

I have a commandline application coded in delphi that I need to call from a normal desktop application (also coded in delphi). In short, I want to call the commandline app and display the text it outputs “live” in a listbox.

It’s been ages since I have played around with the shell, but I distinctly remember that in order to grab the text from a commandline app – I have to use the pipe symbol “>”. Like this:

C:/mycmdapp.exe >c:/result.txt

This will take any text printed to the shell (using writeLn) and dump it to a textfile called “result.txt”.

But.. (and here comes the pickle), I want a live result rather than a backlog file. A typical example is the Delphi compiler itself – which manages to report back to the IDE what is going on. If my memory serves me correctly, I seem to recall that I must create a “pipe” channel (?), and then assign the pipe-name to the shell call.

I have tried to google this but I honestly was unsure of how to formulate it. Hopefully someone from the community can point me in the right direction.

Updated: This question might be identical to How do I run a command-line program in Delphi?. Some of the answers fit what I’m looking for, although the title and question itself is not identical.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T20:10:45+00:00Added an answer on May 28, 2026 at 8:10 pm

    As ever so often Zarco Gajic has a solution: Capture the output from a DOS (command/console) Window. This is a copy from his article for future reference:

    The example runs ‘chkdsk.exe c:\’ and displays the output to Memo1.
    Put a TMemo (Memo1) and a TButton (Button1) on your form. Put this code in the OnCLick event procedure for Button1:

    procedure RunDosInMemo(DosApp: string; AMemo:TMemo);
    const
        READ_BUFFER_SIZE = 2400;
    var
        Security: TSecurityAttributes;
        readableEndOfPipe, writeableEndOfPipe: THandle;
        start: TStartUpInfo;
        ProcessInfo: TProcessInformation;
        Buffer: PAnsiChar;
        BytesRead: DWORD;
        AppRunning: DWORD;
    begin
        Security.nLength := SizeOf(TSecurityAttributes);
        Security.bInheritHandle := True;
        Security.lpSecurityDescriptor := nil;
    
        if CreatePipe({var}readableEndOfPipe, {var}writeableEndOfPipe, @Security, 0) then
        begin
            Buffer := AllocMem(READ_BUFFER_SIZE+1);
            FillChar(Start, Sizeof(Start), #0);
            start.cb := SizeOf(start);
    
            // Set up members of the STARTUPINFO structure.
            // This structure specifies the STDIN and STDOUT handles for redirection.
            // - Redirect the output and error to the writeable end of our pipe.
            // - We must still supply a valid StdInput handle (because we used STARTF_USESTDHANDLES to swear that all three handles will be valid)
            start.dwFlags := start.dwFlags or STARTF_USESTDHANDLES;
            start.hStdInput := GetStdHandle(STD_INPUT_HANDLE); //we're not redirecting stdInput; but we still have to give it a valid handle
            start.hStdOutput := writeableEndOfPipe; //we give the writeable end of the pipe to the child process; we read from the readable end
            start.hStdError := writeableEndOfPipe;
    
            //We can also choose to say that the wShowWindow member contains a value.
            //In our case we want to force the console window to be hidden.
            start.dwFlags := start.dwFlags + STARTF_USESHOWWINDOW;
            start.wShowWindow := SW_HIDE;
    
            // Don't forget to set up members of the PROCESS_INFORMATION structure.
            ProcessInfo := Default(TProcessInformation);
    
            //WARNING: The unicode version of CreateProcess (CreateProcessW) can modify the command-line "DosApp" string. 
            //Therefore "DosApp" cannot be a pointer to read-only memory, or an ACCESS_VIOLATION will occur.
            //We can ensure it's not read-only with the RTL function: UniqueString
            UniqueString({var}DosApp);
    
            if CreateProcess(nil, PChar(DosApp), nil, nil, True, NORMAL_PRIORITY_CLASS, nil, nil, start, {var}ProcessInfo) then
            begin
                //Wait for the application to terminate, as it writes it's output to the pipe.
                //WARNING: If the console app outputs more than 2400 bytes (ReadBuffer),
                //it will block on writing to the pipe and *never* close.
                repeat
                    Apprunning := WaitForSingleObject(ProcessInfo.hProcess, 100);
                    Application.ProcessMessages;
                until (Apprunning <> WAIT_TIMEOUT);
    
                //Read the contents of the pipe out of the readable end
                //WARNING: if the console app never writes anything to the StdOutput, then ReadFile will block and never return
                repeat
                    BytesRead := 0;
                    ReadFile(readableEndOfPipe, Buffer[0], READ_BUFFER_SIZE, {var}BytesRead, nil);
                    Buffer[BytesRead]:= #0;
                    OemToAnsi(Buffer,Buffer);
                    AMemo.Text := AMemo.text + String(Buffer);
                until (BytesRead < READ_BUFFER_SIZE);
            end;
            FreeMem(Buffer);
            CloseHandle(ProcessInfo.hProcess);
            CloseHandle(ProcessInfo.hThread);
            CloseHandle(readableEndOfPipe);
            CloseHandle(writeableEndOfPipe);
        end;
    end;
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin {button 1 code}
       RunDosInMemo('chkdsk.exe c:\',Memo1);
    end;
    

    Update:
    The above example reads the output in one step. Here is another example from DelphiDabbler showing how the output can be read while the process is still running:

    function GetDosOutput(CommandLine: string; Work: string = 'C:\'): string;
    var
      SA: TSecurityAttributes;
      SI: TStartupInfo;
      PI: TProcessInformation;
      StdOutPipeRead, StdOutPipeWrite: THandle;
      WasOK: Boolean;
      Buffer: array[0..255] of AnsiChar;
      BytesRead: Cardinal;
      WorkDir: string;
      Handle: Boolean;
    begin
      Result := '';
      with SA do begin
        nLength := SizeOf(SA);
        bInheritHandle := True;
        lpSecurityDescriptor := nil;
      end;
      CreatePipe(StdOutPipeRead, StdOutPipeWrite, @SA, 0);
      try
        with SI do
        begin
          FillChar(SI, SizeOf(SI), 0);
          cb := SizeOf(SI);
          dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
          wShowWindow := SW_HIDE;
          hStdInput := GetStdHandle(STD_INPUT_HANDLE); // don't redirect stdin
          hStdOutput := StdOutPipeWrite;
          hStdError := StdOutPipeWrite;
        end;
        WorkDir := Work;
        Handle := CreateProcess(nil, PChar('cmd.exe /C ' + CommandLine),
                                nil, nil, True, 0, nil,
                                PChar(WorkDir), 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 + 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;
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a command line application that reads some settings from the app.config file,
We have an application that installs SQL Server Express from the command line and
I have a command line application I need to execute from my PHP web
I have a service application built in Delphi that works great. It does exactly
So I have a process (java commandline application) that is hidden with the output
I have a Delphi application that has many dependencies, and it would be difficult
I have a small command-line application written in C that acts as a wrapper/launcher
I have an application which is built from command line (ANT) using J2ME Polish.
I have a command line Ruby app I'm developing and I want to allow
I've been working on a commandline application, and have recently decided to add a

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.