Tipy a triky v Delphi, díl 102.

Dnes si předvedeme jeden ze způsobů, jak výstup nějaké konzolové aplikace či dávkového souboru odchytit a zobrazit v naší aplikaci.
K čemu to vlastně může být dobré? I v dnešní době se tu a tam občas bez příkazového řádku neobejdeme. Stále existuje poměrně dost velmi užitečných utilit, které existují pouze ve verzi "pro příkazový řádek" a i když budou možná někteří z vás protestovat, je to stále ještě pro řadu úloh velmi elegantní řešení, pro které se nevyplatí programovat robustní aplikaci pod Windows. Naše aplikace pak může podobných externích prográmků či dávkových souborů využívat a proto se nám bude hodit umět odchytit jejich textový výstup.

My pro tento účel použijeme komponentu Memo, která je pro podobné textové výstupy dostačující. Funkci pak aktivujeme pomocí tlačítka, takže tyto dva objekty umístěte na nový formulář. U samotné komponenty Memo můžete nastavit co vás jen napadne, tedy například barvu podkladu, typ písma a další parametry, to záleží jen na vaší potřebě.

unit Unit1;

 interface

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

 type
   TForm1 = class(TForm)
     Memo1: TMemo;
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   private
     { Private declarations }
     function RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;
   public
     { Public declarations }
   end;

 var
   Form1: TForm1;

 implementation

 {$R *.dfm}

 function TForm1.RunCaptured(const _dirName, _exeName, _cmdLine: string): Boolean;
 var
   start: TStartupInfo;
   procInfo: TProcessInformation;
   tmpName: string;
   tmp: THandle;
   tmpSec: TSecurityAttributes;
   return: Cardinal;
 begin
   Result := False;
   try
     tmpName := `Test.tmp`;
     FillChar(tmpSec, SizeOf(tmpSec), #0);
     tmpSec.nLength := SizeOf(tmpSec);
     tmpSec.bInheritHandle := True;
     tmp := CreateFile(PChar(tmpName), Generic_Write, File_Share_Write, @tmpSec, Create_Always, File_Attribute_Normal, 0);
     try
       FillChar(start, SizeOf(start), #0);
       start.cb := SizeOf(start);
       start.hStdOutput := tmp;
       start.dwFlags := StartF_UseStdHandles or StartF_UseShowWindow;
       start.wShowWindow := SW_Minimize;
       if CreateProcess(nil, PChar(_exeName + ` ` + _cmdLine), nil, nil, True, 0, nil, PChar(_dirName), start, procInfo) then
       begin
         SetPriorityClass(procInfo.hProcess, Idle_Priority_Class);
         WaitForSingleObject(procInfo.hProcess, Infinite);
         GetExitCodeProcess(procInfo.hProcess, return);
         Result := (return = 0);
         CloseHandle(procInfo.hThread);
         CloseHandle(procInfo.hProcess);
         CloseHandle(tmp);
         try
           Memo1.Lines.LoadFromFile(tmpName);
         finally
         end;
         DeleteFile(PChar(tmpName));
       end
       else
       begin
         Application.MessageBox(PChar(SysErrorMessage(GetLastError())), `Chyba !!`, MB_OK);
         DeleteFile(PChar(tmpName));
       end;
     except
       CloseHandle(tmp);
       DeleteFile(PChar(tmpName));
       raise;
     end;
   finally
   end;
 end;

 procedure TForm1.Button1Click(Sender: TObject);
 begin
   RunCaptured(`C:\`, `cmd.exe`, `/c dir`);
 end;

 end.

Pohledem do zdrojového kódu zjistíte, že textový výstup není úplně přímý, ale že je použit menší "podvod". Výstup totiž nejprve přesměrujeme do pomocného textového souboru, jehož obsah poté na konci celého procesu načteme do příslušné komponenty Memo a smažeme.

Náš příklad pomocí příkazového řádku vypíše obsah disku C a vzhledem k použití cmd.exe nebude fungovat pod systémy 9x. Pochopitelně vám vůbec nic nebrání si konkrétní parametry a spouštěný program upravit podle svého, protože jinak je samozřejmě příklad funkční i pod 9x. Jednotlivé parametry naší funkce RunCaptured jsou myslím dostatečně jasné a netřeba je vysvětlovat.

Diskuze (8) Další článek: Vyjádření ministra Mlynáře k nové podobě ADSL

Témata článku: Software, Windows, Programování, Trik, Strong, Díl

Určitě si přečtěte


Aktuální číslo časopisu Computer

Test 6 odolných telefonů a 22 powerbank

Srovnání technologií QLED a OLED

Měřte své sportovní výkony

Sady pro chytrou domácnost