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.
Tipy a triky v Delphi, díl 102.
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.

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

8 komentářů

Nejnovější komentáře

  • Radek 21. 8. 2003 15:23:15

    Zrovna nemám čas si s tím hrát, ale čekal bych, že výstup by měl jít...

  • Petr 15. 8. 2003 3:28:40
    Zvlaste kdyz se pripravuji treba takto...
  • Jan Fiala 9. 8. 2003 17:32:23
    Nejsem autor, ale taky se mi to nekdy stane, kdyz pripravuju ukazky....
Určitě si přečtěte

Jak převést PDF do Wordu: 3 způsoby, které můžete použít

Jak převést PDF do Wordu: 3 způsoby, které můžete použít

** Využít můžete přímo Word v rámci balíčku Office ** Zdarma lze využít Google Dokumenty, neporadí si ale s formátováním ** Obrátit se také můžete na specializované stránky

11.  8.  2017 | Vladislav Kluska | 9

USB zařízení je možné odposlouchávat ze sousedního portu

USB zařízení je možné odposlouchávat ze sousedního portu

** Crosstalk byl dřív problém paralelních portů, dnes se ho pokusili prověřit na USB ** Zařízení ze sousedního USB portu může odposlouchávat to vedlejší ** Mohou vznikat záškodnické flašky nebo třeba USB lampičky

14.  8.  2017 | Adam Harmada | 18

Zrušený evropský roaming je brutální vražda virtuálních operátorů

Zrušený evropský roaming je brutální vražda virtuálních operátorů

** Když EU rušila roaming, šla přes mrtvoly ** Tou největší jsou virtuální operátoři ** Vlastně je překvapivé, že už nepadají jeden po druhém

12.  8.  2017 | Filip Kůžel | 85

Obrněná raketová vozidla Stryker budou bojovat proti dronům a letadlům

Obrněná raketová vozidla Stryker budou bojovat proti dronům a letadlům

** Původně kanadská obrněná bojová vozidla Stryker od společnosti General Dynamics existují v celé řadě verzí ** Některá slouží k průzkumu, jiná jsou vybavena těžkými zbraněmi ** Nyní bylo představeno nové raketové vozidlo Stryker, které je vyzbrojeno raketami Sidewinder a Hellfire

11.  8.  2017 | Stanislav Mihulka | 1


Aktuální číslo časopisu Computer

Velký test NVMe a SATA SSD

Máte slabý signál
Wi-Fi? Poradíme!

Jak umělá inteligence opravuje fotky

Kupujete dron? Ty levné se nevyplatí