Dedinčan odporúča...

Joomla! logoJoomla! je výkonný otvorený Systém na správu obsahu (Content Management Systems). Systém je používaný po celom svete, od jednoduchých webových stránok, po komplexné podnikové aplikácie. Joomla! sa ľahko inštaluje, je jednoduchý na správu a...

Externé programy

Kategória: Lazarus
Upravené: sobota, 25. júl 2009

S rôznych dôvodov býva potrebné spúšťať v svojom programe programy externé, či sa už jedná o nejaké systémové nástroje alebo bežné používateľské programy. Verte mi alebo nie, nie je nič jednoduchšie.V Lazarovi je na to pripravená trieda TProcess, ktorá je potomkom triedy TComponent.

TProcess

Ako som spomínal, trieda TProcess je potomkom triedy TComponent a možno ju použiť priamo v kóde programu, ale je dostupná aj ako komponent v palete komponentov na záložke System. Ja však použijem prvý spôsob, a topoužívanie priamo v kóde programu. V mojich príkladoch neukážem použitie všetkých metód a vlastností triedy, ale pokúsim sa položiť slušný základ pre jej ďalšie používanie. Takže, ktoré možnosti si vlastne ukážeme?

Najprv si vytvoríme algoritmus pre spustenie GUI programu KCalc, ktorý bude bežať nezávisle na našom programe, teda aj po jeho ukončení. Keďže však je niekedy vhodné, aby náš program počkal na ukončenie procesu, ktorý spustil, ukážeme si aj ako dosiahnuť takéto správanie. Toto čakanie si ukážeme na rovnakom programe, pretože si myslím, že práve na GUI programe najlepšie uvidíte to čakanie na ukončenie. Potom sa presunieme na konzolové programy. Tieto programy často spúšťame kvôli tomu, aby sme dostali ich výstup, takže najprv si ukážeme ako sa k ich výstupu dopátrať a dostať ho do formulára. No a nakoniec si ukážeme, akospustiť program, ktorý pre svoj beh potrebuje práva superpoužívateľa.

Formulár

Pre naše príkaldy sivytvorte nový projekt a v ňom formulár, podobný tomu na obrázku, ktorý obsahuje jeden komponent TLabel, jeden TMemo, zatváracie tlačítko a štyri tlačítka, z ktorých každé bude spúšťať jeden z mojich príkladov.

Formulár pre TProcess

Aby ste mali predstavu aj o menách komponentov, pridávam deklaráciu formulára. Z deklarácie som vynechal obsluhy udalostí tlačítiek, ale to nie je dôležité. Ak teda chcete jednoducho kopírovať ukážky kódu, pomenujte si všetky prvky tak ako je v príklade:

Formulár frmMain
type   { TfrmMain } TfrmMain = class(TForm) BitBtn1: TBitBtn; btnKCalc: TButton; btnKCalcWait: TButton; btnIptabl: TButton; btnNetst: TButton; Label1: TLabel; memVyst: TMemo; private { private declarations } public { public declarations } end;

Príklady použitia

Samostatný GUI program

V tomto príklade, ktorý je naozaj základným použitím triedy TProcess, pripravím obsluhu udalosti OnClick tlačítka btnKCalc, dúfam, že priložené komentáre vravia za všetko:

Spustenie samostatného GUI
procedure TfrmMain.btnKCalcClick(Sender: TObject); var Proc: TProcess; Retazec: String; begin // Vytvorenie objektu Proc := TProcess.Create(nil); // nastavenie príkazového riadku (vrátane prípadných argumentov) Proc.CommandLine := 'kcalc'; // spustenie procesu Proc.Execute; // zapísanie ID a návratovej hodnoty Retazec := 'Proces s ID ' + IntToStr(Proc.ProcessID) + ' spustený'; memVyst.Lines.Add(Retazec); // uvoľnenie projektu (v tomto prípade aj pred ukončením procesu) Proc.Free; end;

Vzhľadom k tomu, že pri uvoľnení obejktu Proc, proces ešte môže (a veľmi pravdepodobne aj bude) bežať, nemôžeme pri takomto riešení zisťovať návratovú hodnotu spusteného procesu. Takže ako jedinú interakciu ukazujem vypísanie ID vytvoreného procesu. Pokojne program spustite a vyskúšajte, že po kliknutí na tlačítko Kalkulacka, sa spustí program KCalc, a tento ostane spustený aj keď svoj program ukončíte.

Čakanie na GUI program

V tomto prípadepoužijeme skoro robnaký kód ako v predchdázajúcom príklade, len pridáme jednu vošbu spustenia poWaitOnExit, ktorá má za následok, že volanie metódy Execute skončí, až po skončení nami spusteného procesu:

Čakanie na skončenie procesu
procedure TfrmMain.btnKCalcWaitClick(Sender: TObject); var Proc: TProcess; Retazec: String; begin // Vytvorenie objektu Proc := TProcess.Create(nil); // nastavenie príkazového riadku (vrátane prípadných argumentov) Proc.CommandLine := 'kcalc';> // nasatvenie volieb spustenia (čakať na skončenie) Proc.Options := Proc.Options + [poWaitOnExit]; // spustenie procesu Proc.Execute; // zapísanie ID a návratovej hodnoty Retazec := 'Proces s ID ' + IntToStr(Proc.ProcessID) + ' vrátil: ' + IntToStr(Proc.ExitStatus); memVyst.Lines.Add(Retazec); // uvoľnenie projektu (v tomto prípade až po ukončení procesu) Proc.Free; end;

Keďže teraz metóda Execute čaká na skončenie procesu, môžeme po nej získať návratový kód procesu, ktorý vypisujeme do TMemo. Po spustení programu si môežte porovnať správenie, keď kliknete na tlačítko Kalkul Wait.

Získanie výstupu

Teraz prejdeme od GUI programov ku konzolovým, ktoré sú často charakteristické svojim výstupom na konzolu a práve preto tieto programy voláme. Takže potrebujeme nejakým spôsobom ich výstup zachytiť a potom ho predáme do nášho TMemo. Realizácia zachytenia výstupu procesu je založená na použití volieb spustenia poWaitOnExit a poUsePipes, ktoré zaistia okrem čakania na skončenie procesu aj použitie rúr (pipe) na presmerovanie výstupu. Samotný výstup potom načítame prostredníctvom streamu z vlastnosti Output. Ako príklad používam výstup programu netstat, ktorému pridávam aj nejaké voľby:

Výstup procesu
procedure TfrmMain.btnNetstClick(Sender: TObject); var Proc: TProcess; Retazec: String; begin // Vytvorenie objektu Proc := TProcess.Create(nil); // nastavenie príkazového riadku (vrátane prípadných argumentov) Proc.CommandLine := 'netstat -tuln'; // nasatvenie volieb spustenia (čakať na skončenie a použiť rúru) Proc.Options := Proc.Options + [poWaitOnExit, poUsePipes]; // spustenie procesu Proc.Execute; // zapísanie výstupu memVyst.Lines.LoadFromStream(Proc.Output); memVyst.Lines.Add(''); // zapísanie ID a návratovej hodnoty Retazec := 'Proces s ID ' + IntToStr(Proc.ProcessID) + ' vrátil: ' + IntToStr(Proc.ExitStatus); memVyst.Lines.Add(Retazec); // uvoľnenie projektu (v tomto prípade až po ukončení procesu) Proc.Free; end;

Všimnite si, že po vykonaní výstup programu nestat prepíše celý obsah TMemo.

Získanie práv superpoužívateľa

Niekedy je potrebné spustiť systémový program, ktorý však vyžaduje práva superpoužívateľa root. Ani to však nie je problém, v tomto príklade používam nástroj kdesu, ktorý zaistí pridelenie príslušných práv a aj prípadné zadanie hesla. Použitie su, či gksu je veľmi podobné.

Práva root
procedure TfrmMain.btnIptablClick(Sender: TObject); var Proc: TProcess; Retazec: String; StrList: TStringList; begin // Vytvorenie objektu Proc := TProcess.Create(nil); // nastavenie príkazového riadku (vrátane prípadných argumentov) Proc.CommandLine := 'kdesu -t "iptables -L"'; // nasatvenie volieb spustenia (čakať na skončenie a použiť rúru) Proc.Options := Proc.Options + [poWaitOnExit, poUsePipes]; // spustenie procesu Proc.Execute; // vytvorenie TStringList StrList := TStringList.Create; // zapísanie výstupu StrList.LoadFromStream(Proc.Output); memVyst.Lines.AddStrings(StrList); memVyst.Lines.Add(''); // zapísanie ID a návratovej hodnoty Retazec := 'Proces s ID ' + IntToStr(Proc.ProcessID) + ' vrátil: ' + IntToStr(Proc.ExitStatus); memVyst.Lines.Add(Retazec); // uvoľnenie projektu (v tomto prípade až po ukončení procesu) AStringList.Free; Proc.Free; end;

Nástroju kdesu musíme zadať parameter -t, ktorý sa postará o výstup zadaného programu do konzoly (čiže do našej rúry), potrebné je tiež príkaz aj s jeho parametrom uzavrieť do úvodzoviek, pretože inak sa o použitie parametra -L pokúsi kdesu. Za zmienku stojí ešte to, že riešenie výstupu procesu do TMemo tentokrát jeho obsah nenahradí, ale pridá na koniec.

Záver

Pre reálne využitie je určite viac ako vhodné pridať spracovanie výnimiek (chýb), nechcel som však príklady priveľmi komplikovať, ale zameral som sa na použitie triedy TProcess. Všetky tieto príklady neriešia jeden problém, a tým je spracovanie veľkého výstupu, ktorý môže spôsobiť uviaznutie programu. Postup riešenia problému, ak výstup presiahne 2048 B je uvedený v dokumentácii Lazara.

Pridajte svoj komentár...

    Copyright © 2008 - 2012 Sprievodca dedinčana... Niektoré práva vyhradené.
    Ak nie je uvedené inak, obsah podlieha licencii „Creative Commons Uveďte autora – Zachovajte licenciu 3.0 Unported

    Nenasledovať tento odkaz, inak budete maž zakázaný prístup na stránku!