Sign in Join
Wiki copytemporary

Executing External Programs/sk: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Executing External Programs/sk

OldNewLine
1+## Úvod
2+
3+Je mnoho spôsobov ako spustiť externé programy. Zameriame sa na jeden z nich.
4+
5+## SysUtils.ExecuteProcess
6+
7+najjednoduchší spôsob, ak nepotrebujete rúry (*pipes*) alebo žiadne formu ovládania je jednoducho použiť
8+
9+``` pascal
10+ SysUtils.ExecuteProcess('/full/path/to/binary',['arg1','arg2']);
11+```
12+
13+## TProcess
14+
15+Môžete použiť TProcess na spustenie externých programov. Výhody tohoto spôsobu sú:
16+
17+- Nezávislý na platforme
18+- Schopnosť čítať zo stdin a stdout.
19+
20+
21+**Poznámka**: TProcess nie je terminal/shell! Nemôžete priamo spustiť alebo presmerovať výstup pomocou operátorov ako "\|", "\>", "\<", "&" atď. Možno získať rovnaký výsledok s TProcess pomocou Pascal, príklady nasledujú...
22+
23+### Jednoduchý príklad
24+
25+``` pascal
26+ // Toto je ukážkový program ktorý vám ukáže ako
27+ // spustiť externý program.
28+ program launchprogram;
29+
30+ // Tu si "použijeme" unity ktoré budeme potrebovať
31+ uses
32+ Classes, SysUtils, Process;
33+
34+ // Toto je definícia premennej APRocess
35+ // typu "TProcess"
36+ var
37+ AProcess: TProcess;
38+
39+ // Začiatok programu
40+ begin
41+ // Vytvoríme objekt TProcess
42+ // pridelíme ho do premennej AProcess
43+ AProcess := TProcess.Create(nil);
44+
45+ // Povieme novému procesu aký príkaz má vykonať
46+ // Použime FPC prekladač
47+ AProcess.CommandLine := 'ppc386 -h';
48+
49+ // Definujeme nastavenie pre spustenie.
50+ // Toto nastavenie zaručí že náš program
51+ // nebude pokračovať až kým sa proces neskončí
52+ AProcess.Options := AProcess.Options + [poWaitOnExit];
53+
54+ // Teraz keď už proces vie čo má robiť
55+ // ho môžeme spustiť.
56+ AProcess.Execute;
57+
58+ // Toto sa dosiahne až po skončení procesu.
59+ AProcess.Free;
60+ end.
61+```
62+
63+To je všetko! Práve ste sa naučili ako spustit externý program použitím TProcess.
64+
65+To je všetko pekné, ale ako získam výstup spusteného programu? Tak sa na to pozrime, trochu rozšírime náš priklad.
66+
67+### Vylepšený príklad
68+
69+``` pascal
70+ // Toto je ukážkový program ktorý vám ukáže ako
71+ // spustiť externý program.
72+ program launchprogram;
73+
74+ // Tu si "použijeme" unity ktoré budeme potrebovať
75+ uses
76+ Classes, SysUtils, Process;
77+
78+ // Toto je definícia premennej APRocess
79+ // typu "TProcess"
80+ // Teraz pridáme aj TStringList aby sme
81+ // mohli uložiť výstup procesu.
82+ var
83+ AProcess: TProcess;
84+ AStringList: TStringList;
85+
86+ // Začiatok programu
87+ begin
88+ // Vytvoríme objekt TProcess
89+ // pridelíme ho do premennej AProcess
90+ AProcess := TProcess.Create(nil);
91+
92+ // Vytvoríme TStringList a pridelíme ho
93+ AStringList := TStringList.Create;
94+
95+ // Povieme novému procesu aký príkaz má vykonať
96+ // Použime FPC prekladač
97+ AProcess.CommandLine := 'ppc386 -h';
98+
99+ // Definujeme nastavenie pre spustenie.
100+ // Toto nastavenie zaručí že náš program
101+ // nebude pokračovať až kým sa proces neskončí
102+ // Zároveň ho nastavíme tak, aby sme mohli
103+ // čítať výstup.
104+ AProcess.Options := AProcess.Options + [poWaitOnExit, poUsePipes];
105+
106+ // Teraz keď už proces vie čo má robiť
107+ // ho môžeme spustiť.
108+ AProcess.Execute;
109+
110+ // Toto sa dosiahne až po skončení procesu.
111+
112+ // Teraz načítame výstup programu
113+ // do TStringListu.
114+ AStringList.LoadFromStream(AProcess.Output);
115+
116+ // Uložíme výstup do súboru
117+ AStringList.SaveToFile('output.txt');
118+
119+ // Teraz keď je už výstup uložený
120+ // môžeme uvolniť objekty.
121+ AStringList.Free;
122+ AProcess.Free;
123+ end.
124+```
125+
126+### Čítanie veľkého výstupu
127+
128+V predchádzajúcom príklade sme čakali na ukončenie programu a potom sme čítali čo mal program zapísané do výstupu. Ale predstavte si, že program zapisuje na výstup veľké množstvo dát, rúra sa plní a volaný program čaká na jej vyprázdnenie (prečítanie). Ale volajúci program z rúry nečíta, pretože čaká na ukončenie volaného programu. Nastalo uviaznutie.
129+
130+Takže nasledujúci príklad nepoužíva poWaitOnExit, ale číta z výstupu, zatiaľ čo program stále beží. Výstup je uchovávaný v pamäťovom streame, ktorý môže byť neskôr použitý na prečítanie výstupu do TStringList.
131+
132+``` pascal
133+ program procoutlarge;
134+ {
135+ Copyright (c) 2004 by Marc Weustink
136+
137+ Tento príklad je vytvorený v nádeji, že bude užitočný,
138+ ale BEZ AKEJKOĽVEK ZÁRUKY; dokonca bez implicitnej záruky
139+ MERCHANTABILITY alebo FITNESS FOR A PARTICULAR PURPOSE.
140+ }
141+
142+ uses
143+ Classes, Process, SysUtils;
144+
145+ const
146+ READ_BYTES = 2048;
147+
148+ var
149+ S: TStringList;
150+ M: TMemoryStream;
151+ P: TProcess;
152+ n: LongInt;
153+ BytesRead: LongInt;
154+
155+ begin
156+ // Nemôžeme tu použiť poWaitOnExit, lebo nepoznáme
157+ // veľkosť výstupu. V Linuxe je veľkosť
158+ // výstupnej rúry 2 kB. Ak je výstupných dátviac,
159+ // musíme dáta prečítať. To však nie je možné, keďže
160+ // sme čakajúci. Takže by tu nastalo uviaznutie.
161+ //
162+ // Na buferovanie výstupu použijeme dočasný Memorystream
163+
164+ M := TMemoryStream.Create;
165+ BytesRead := 0;
166+
167+ P := TProcess.Create(nil);
168+ P.CommandLine := 'ppc386 -va bogus.pp';
169+ P.Options := [poUsePipes];
170+ WriteLn('-- executing --');
171+ P.Execute;
172+ while P.Running do
173+ begin
174+ // overenie, že máme dosť priestoru
175+ M.SetSize(BytesRead + READ_BYTES);
176+
177+ // skús ho prečítať
178+ n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
179+ if n > 0
180+ then begin
181+ Inc(BytesRead, n);
182+ Write('.')
183+ end
184+ else begin
185+ // žiadne dáta, počkať 100 ms
186+ Sleep(100);
187+ end;
188+ end;
189+ // čítať poslednú časť
190+ repeat
191+ // overenie, že máme dosť priestoru
192+ M.SetSize(BytesRead + READ_BYTES);
193+ // skús ho prečítať
194+ n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
195+ if n > 0
196+ then begin
197+ Inc(BytesRead, n);
198+ Write('.');
199+ end;
200+ until n <= 0;
201+ if BytesRead > 0 then WriteLn;
202+ M.SetSize(BytesRead);
203+ WriteLn('-- executed --');
204+
205+ S := TStringList.Create;
206+ S.LoadFromStream(M);
207+ WriteLn('-- linecount = ', S.Count, ' --');
208+ for n := 0 to S.Count - 1 do
209+ begin
210+ WriteLn('| ', S[n]);
211+ end;
212+ WriteLn('-- end --');
213+ S.Free;
214+ P.Free;
215+ M.Free;
216+ end.
217+```
218+
219+### Použitie vstupu a výstupu z TProcess
220+
221+Viz príklad processdemo na [Lazarus-CCR SVN](https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/examples/process).
222+
223+### Pokyny pre použitie TProcess
224+
225+Ak vytvárate cez platformný program, môžete zmeniť príkazový riadok v závislosti na OS, pomocou direktív "{\$IFDEF}s" a "{\$ENDIF}s".
226+
227+Príklad:
228+
229+``` pascal
230+ {...}
231+ AProcess:TProcess.Create(nil)
232+ {$IFDEF WIN32}
233+ AProcess.CommandLine := 'calc.exe'; //Windows Calc
234+ {$ENDIF}
235+ {$IFDEF LINUX}
236+ AProcess.CommandLine := 'kcalc'; //KDE Calc
237+ {$ENDIF}
238+ AProcess.Execute; //in alternative, you can use AProcess.Active:=True
239+ {...}
240+```
241+
242+### Príklad komunikácie s procesom aspell
243+
244+V zdrojovom kóde [pasdoc](http://pasdoc.sourceforge.net/) môžete nájsť dve unity, ktoré vykonávajú kontrolu pravopisu komunikáciou s bežiacim procesom aspell cez rúry:
245+
246+- [PasDoc_ProcessLineTalk.pas unit](http://pasdoc.svn.sourceforge.net/viewvc/*checkout*/pasdoc/trunk/source/component/PasDoc_ProcessLineTalk.pas) implementuje triedu TProcessLineTalk, potomka TProcess, ktorú možno jednoducho použiť na komunikáciu s ktorýmkoľvek procesom na báze riadok-po-riadku.
247+- [PasDoc_Aspell.pas unit](http://pasdoc.svn.sourceforge.net/viewvc/*checkout*/pasdoc/trunk/source/component/PasDoc_Aspell.pas) implementuje triedu TAspellProcess, ktorá vykonáva kontrolu pravopisu pomocou základnej inštancie TProcessLineTalk pre spustenie aspell a komunikáciu so spusteným procesom aspell.
248+
249+Obe jednotky sú vcelku nezávislé od zvyšku zdrojového kódu pasdoc, takže môžu poslúžiť ako príklady skutočného použitia TProcess na spustenie a komunikáciu s inými programmi cez rúry.
250+
251+---
252+*From the Free Pascal wiki, page "Executing External Programs/sk", as it stood on 2020-02-14 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history