Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

pulling console screen output into variable

Posted on 1999-07-21
4
Medium Priority
?
278 Views
Last Modified: 2010-04-04
If I execute a command, for example "dir *.*" using something like winexec() can I pull the output right into a variable?

As opposed to piping the output to a file and then reading the file?

thanks in advance.
0
Comment
Question by:TMcSinly
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
4 Comments
 
LVL 13

Expert Comment

by:Epsylon
ID: 1390236
I think Mike (Lischke) knows the answer on this question, so Mike, go ahead   :o)
0
 
LVL 12

Accepted Solution

by:
rwilson032697 earned 400 total points
ID: 1390237
(Credit to Philip Leighs for this code...)

The best way to do what you want is to use pipes.

The code below takes the file name of a console app, and two TStringLists.
The exe is executed (and is invisible). When it terminates, the first string list contains the standard output. The second string list contains anything that was written to standard error.

Add a TButton and two TMemos to a form, then paste in the code below. You might need to change to path of the exe!

BTW, if you want to pass arguments to the exe, then change this:
    Res := CreateProcess(
        PChar(ExeName),
        nil,
to
    Res := CreateProcess(
        PChar(ExeName),
        PChar(' ' + Args),
The space before Args *is* significant.

Cheers,

Raymond.

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Memo1: TMemo;
    Memo2: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure ExecConsoleApp(ExeName: string; Output: TStringList; Errors: TStringList);
  var sa: TSECURITYATTRIBUTES;
      si: TSTARTUPINFO;
      pi: TPROCESSINFORMATION;
      hPipeOutputRead: THANDLE;
      hPipeOutputWrite: THANDLE;
      hPipeErrorsRead: THANDLE;
      hPipeErrorsWrite: THANDLE;

      Res: Boolean;
      env: array [0..100] of Char;

      bTest: Boolean;
      dwNumberOfBytesRead: DWORD;
      szBuffer: array [0..256] of Char;
      Stream: TMemoryStream;
  begin
    sa.nLength := sizeof(sa);
    sa.bInheritHandle := true;
    sa.lpSecurityDescriptor := nil;

    CreatePipe(hPipeOutputRead,
               hPipeOutputWrite,
               @sa,
               0);
    CreatePipe(hPipeErrorsRead,
               hPipeErrorsWrite,
               @sa,
               0);

    ZeroMemory(@env, SizeOf(env));
    ZeroMemory(@si, SizeOf(si));
    ZeroMemory(@pi, SizeOf(pi));
    si.cb := SizeOf(si);
    si.dwFlags := STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES;
    si.wShowWindow := SW_HIDE;
    si.hStdInput   := 0;
    si.hStdOutput  := hPipeOutputWrite;
    si.hStdError   := hPipeErrorsWrite;

    Res := CreateProcess(
        PChar(ExeName),
        nil,
        nil,
        nil,
        true,
        CREATE_NEW_CONSOLE or NORMAL_PRIORITY_CLASS,
        @env,
        nil,
        si,
        pi);
    if not Res then
      begin
        CloseHandle (hPipeOutputRead);
        CloseHandle(hPipeOutputWrite);
        CloseHandle (hPipeErrorsRead);
        CloseHandle(hPipeErrorsWrite);
        raise Exception.Create('Unable to execute ' + ExeName);
        exit;
      end;

    CloseHandle(hPipeOutputWrite);
    CloseHandle(hPipeErrorsWrite);

    //Read output pipe
    Stream := TMemoryStream.Create;
    try
      while true do
        begin
          bTest:=ReadFile(
                hPipeOutputRead,
                szBuffer,
                256,
                dwNumberOfBytesRead,
                nil);
          if not bTest then
            begin
              break;
            end;
          Stream.Write(szBuffer, dwNumberOfBytesRead);
        end;
      Stream.Position := 0;
      Output.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;

    //Read error pipe
    Stream := TMemoryStream.Create;
    try
      while true do
        begin
          bTest:=ReadFile(
                hPipeErrorsRead,
                szBuffer,
                256,
                dwNumberOfBytesRead,
                nil);
          if not bTest then
            begin
              break;
            end;
          Stream.Write(szBuffer, dwNumberOfBytesRead);
        end;
      Stream.Position := 0;
      Errors.LoadFromStream(Stream);
    finally
      Stream.Free;
    end;

    WaitForSingleObject (pi.hProcess, INFINITE);
    CloseHandle (pi.hProcess);
    CloseHandle (hPipeOutputRead);
    CloseHandle (hPipeErrorsRead);
  end;

procedure TForm1.Button1Click(Sender: TObject);
  var o, e: TStringList;
begin
  o := TStringList.Create;
  e := TStringList.Create;
  ExecConsoleApp('c:\program files\borland\delphi4\bin\convert.exe', o, e);
  Memo1.Lines.Assign(o);
  Memo2.Lines.Assign(e);
  o.Free;
  e.Free;
end;

end.

0
 
LVL 10

Expert Comment

by:Lischke
ID: 1390238
Raymond was actually faster :-)

Ciao, Mike
0
 

Author Comment

by:TMcSinly
ID: 1390239
thats perfect. thanks
0

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
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…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Want to learn how to record your desktop screen without having to use an outside camera. Click on this video and learn how to use the cool google extension called "Screencastify"! Step 1: Open a new google tab Step 2: Go to the left hand upper corn…
Suggested Courses

705 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