Sign in Join
Wiki copytemporary

Executing External Programs/sk: what changed

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

OldNewLine
1+## Contents
2+
3+ * 1 Úvod
4+ * 2 SysUtils.ExecuteProcess
5+ * 3 TProcess
6+ * 3.1 Jednoduchý príklad
7+ * 3.2 Vylepšený príklad
8+ * 3.3 Čítanie veľkého výstupu
9+ * 3.4 Použitie vstupu a výstupu z TProcess
10+ * 3.5 Pokyny pre použitie TProcess
11+ * 3.6 Príklad komunikácie s procesom aspell
12+
113## Úvod
214
3-Je mnoho spôsobov ako spustiť externé programy. Zameriame sa na jeden z nich.
15+Je mnoho spôsobov ako spustiť externé programy. Zameriame sa na jeden z nich.
416
517## SysUtils.ExecuteProcess
618
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']);
19+najjednoduchší spôsob, ak nepotrebujete rúry (_pipes_) alebo žiadne formu ovládania je jednoducho použiť
1120```
21+SysUtils.ExecuteProcess('/full/path/to/binary',['arg1','arg2']);
22+```
1223
1324## TProcess
1425
15-Môžete použiť TProcess na spustenie externých programov. Výhody tohoto spôsobu sú:
26+Môžete použiť TProcess na spustenie externých programov. Výhody tohoto spôsobu sú:
1627
17-- Nezávislý na platforme
18-- Schopnosť čítať zo stdin a stdout.
28+ * Nezávislý na platforme
29+ * Schopnosť čítať zo stdin a stdout.
1930
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ú...
31+ **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ú...
2232
2333### 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.
6134```
35+// Toto je ukážkový program ktorý vám ukáže ako
36+ // spustiť externý program.
37+ program launchprogram;
38+
39+ // Tu si "použijeme" unity ktoré budeme potrebovať
40+ uses
41+ Classes, SysUtils, Process;
42+
43+ // Toto je definícia premennej APRocess
44+ // typu "TProcess"
45+ var
46+ AProcess: TProcess;
47+
48+ // Začiatok programu
49+ begin
50+ // Vytvoríme objekt TProcess
51+ // pridelíme ho do premennej AProcess
52+ AProcess := TProcess.Create(nil);
53+
54+ // Povieme novému procesu aký príkaz má vykonať
55+ // Použime FPC prekladač
56+ AProcess.CommandLine := 'ppc386 -h';
57+
58+ // Definujeme nastavenie pre spustenie.
59+ // Toto nastavenie zaručí že náš program
60+ // nebude pokračovať až kým sa proces neskončí
61+ AProcess.Options := AProcess.Options + [poWaitOnExit];
62+
63+ // Teraz keď už proces vie čo má robiť
64+ // ho môžeme spustiť.
65+ AProcess.Execute;
66+
67+ // Toto sa dosiahne až po skončení procesu.
68+ AProcess.Free;
69+ end.
70+```
6271
63-To je všetko! Práve ste sa naučili ako spustit externý program použitím TProcess.
72+To je všetko! Práve ste sa naučili ako spustit externý program použitím TProcess.
6473
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.
74+To je všetko pekné, ale ako získam výstup spusteného programu? Tak sa na to pozrime, trochu rozšírime náš priklad.
6675
6776### 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.
12477```
78+// Toto je ukážkový program ktorý vám ukáže ako
79+ // spustiť externý program.
80+ program launchprogram;
81+
82+ // Tu si "použijeme" unity ktoré budeme potrebovať
83+ uses
84+ Classes, SysUtils, Process;
85+
86+ // Toto je definícia premennej APRocess
87+ // typu "TProcess"
88+ // Teraz pridáme aj TStringList aby sme
89+ // mohli uložiť výstup procesu.
90+ var
91+ AProcess: TProcess;
92+ AStringList: TStringList;
93+
94+ // Začiatok programu
95+ begin
96+ // Vytvoríme objekt TProcess
97+ // pridelíme ho do premennej AProcess
98+ AProcess := TProcess.Create(nil);
99+
100+ // Vytvoríme TStringList a pridelíme ho
101+ AStringList := TStringList.Create;
102+
103+ // Povieme novému procesu aký príkaz má vykonať
104+ // Použime FPC prekladač
105+ AProcess.CommandLine := 'ppc386 -h';
106+
107+ // Definujeme nastavenie pre spustenie.
108+ // Toto nastavenie zaručí že náš program
109+ // nebude pokračovať až kým sa proces neskončí
110+ // Zároveň ho nastavíme tak, aby sme mohli
111+ // čítať výstup.
112+ AProcess.Options := AProcess.Options + [poWaitOnExit, poUsePipes];
113+
114+ // Teraz keď už proces vie čo má robiť
115+ // ho môžeme spustiť.
116+ AProcess.Execute;
117+
118+ // Toto sa dosiahne až po skončení procesu.
119+
120+ // Teraz načítame výstup programu
121+ // do TStringListu.
122+ AStringList.LoadFromStream(AProcess.Output);
123+
124+ // Uložíme výstup do súboru
125+ AStringList.SaveToFile('output.txt');
126+
127+ // Teraz keď je už výstup uložený
128+ // môžeme uvolniť objekty.
129+ AStringList.Free;
130+ AProcess.Free;
131+ end.
132+```
125133
126134### Čítanie veľkého výstupu
127135
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.
136+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.
131137
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);
138+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.
139+```
140+program procoutlarge;
141+ {
142+ Copyright (c) 2004 by Marc Weustink
176143
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.
144+ Tento príklad je vytvorený v nádeji, že bude užitočný,
145+ ale BEZ AKEJKOĽVEK ZÁRUKY; dokonca bez implicitnej záruky
146+ MERCHANTABILITY alebo FITNESS FOR A PARTICULAR PURPOSE.
147+ }
148+
149+ uses
150+ Classes, Process, SysUtils;
151+
152+ const
153+ READ_BYTES = 2048;
154+
155+ var
156+ S: TStringList;
157+ M: TMemoryStream;
158+ P: TProcess;
159+ n: LongInt;
160+ BytesRead: LongInt;
161+
162+ begin
163+ // Nemôžeme tu použiť poWaitOnExit, lebo nepoznáme
164+ // veľkosť výstupu. V Linuxe je veľkosť
165+ // výstupnej rúry 2 kB. Ak je výstupných dátviac,
166+ // musíme dáta prečítať. To však nie je možné, keďže
167+ // sme čakajúci. Takže by tu nastalo uviaznutie.
168+ //
169+ // Na buferovanie výstupu použijeme dočasný Memorystream
170+
171+ M := TMemoryStream.Create;
172+ BytesRead := 0;
173+
174+ P := TProcess.Create(nil);
175+ P.CommandLine := 'ppc386 -va bogus.pp';
176+ P.Options := [poUsePipes];
177+ WriteLn('-- executing --');
178+ P.Execute;
179+ while P.Running do
180+ begin
181+ // overenie, že máme dosť priestoru
182+ M.SetSize(BytesRead + READ_BYTES);
183+
184+ // skús ho prečítať
185+ n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
186+ if n > 0
187+ then begin
188+ Inc(BytesRead, n);
189+ Write('.')
190+ end
191+ else begin
192+ // žiadne dáta, počkať 100 ms
193+ Sleep(100);
194+ end;
195+ end;
196+ // čítať poslednú časť
197+ repeat
198+ // overenie, že máme dosť priestoru
199+ M.SetSize(BytesRead + READ_BYTES);
200+ // skús ho prečítať
201+ n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
202+ if n > 0
203+ then begin
204+ Inc(BytesRead, n);
205+ Write('.');
206+ end;
207+ until n <= 0;
208+ if BytesRead > 0 then WriteLn;
209+ M.SetSize(BytesRead);
210+ WriteLn('-- executed --');
211+
212+ S := TStringList.Create;
213+ S.LoadFromStream(M);
214+ WriteLn('-- linecount = ', S.Count, ' --');
215+ for n := 0 to S.Count - 1 do
216+ begin
217+ WriteLn('| ', S[n]);
218+ end;
219+ WriteLn('-- end --');
220+ S.Free;
221+ P.Free;
222+ M.Free;
223+ end.
217224```
218225
219226### Použitie vstupu a výstupu z TProcess
220227
221-Viz príklad processdemo na [Lazarus-CCR SVN](https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/examples/process).
228+Viz príklad processdemo na [Lazarus-CCR SVN](<https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/examples/process>).
222229
223230### Pokyny pre použitie TProcess
224231
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:
232+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".
228233
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- {...}
234+Príklad:
240235```
236+{...}
237+ AProcess:TProcess.Create(nil)
238+ {$IFDEF WIN32}
239+ AProcess.CommandLine := 'calc.exe'; //Windows Calc
240+ {$ENDIF}
241+ {$IFDEF LINUX}
242+ AProcess.CommandLine := 'kcalc'; //KDE Calc
243+ {$ENDIF}
244+ AProcess.Execute; //in alternative, you can use AProcess.Active:=True
245+ {...}
246+```
241247
242248### Príklad komunikácie s procesom aspell
243249
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:
250+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:
245251
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.
252+ * [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.
253+ * [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.
248254
249255Obe 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.
250256
251257---
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).*
258+*From the Free Pascal wiki, page "Executing External Programs/sk", as the Internet Archive kept it on 2022-12-09. 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