Sign in Join
Wiki copytemporary

Executing External Programs/fr: what changed

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

OldNewLine
1-## Contents
2-
3- * 1 Introduction
4- * 2 SysUtils.ExecuteProcess
5- * 3 TProcess
6- * 3.1 Un exemple simple
7- * 3.2 Un exemple amélioré
8- * 3.3 Lire une grosse sortie
9- * 3.4 Employer l'entrée et la sortie d'un TProcess
10- * 3.5 Remarque sur l'utilisation de TProcess
11- * 3.6 Exemple de "Dialogue" avec le processus aspell
12-
131## Introduction
142
15-Il y a différentes manière de lancer un programme externe, mais nous ne nous concentrerons que sur une seule : [TProcess](<http://lazarus-ccr.sourceforge.net/docs/fcl/process/tprocess.html> "doc:fcl/process/tprocess.html").
3+Il y a différentes manière de lancer un programme externe, mais nous ne nous concentrerons que sur une seule : [[doc:fcl/process/tprocess.html|TProcess]].
164
17-Si vous utilisez toujours **ShellExecute** et/ou **WinExec** sous Delphi, vous devriez utilisez TProcess comme alternative sous FPC/Lazarus (cela fonctionne également si vous l'utilisez sous Linux, car TProcess est multi-plateforme).
5+Si vous utilisez toujours **ShellExecute** et/ou **WinExec** sous Delphi, vous devriez utilisez TProcess comme alternative sous FPC/Lazarus (cela fonctionne également si vous l'utilisez sous Linux, car TProcess est multi-plateforme).
186
19-**Note :** FPC/Lazarus supporte **ShellExecute** et/ou **WinExec** , mais uniquement sous Win32. Si votre programme est multi-plateforme, utilisez TProcess, c'est la meilleure solution !
7+**Note :** FPC/Lazarus supporte **ShellExecute** et/ou **WinExec**, mais uniquement sous Win32. Si votre programme est multi-plateforme, utilisez TProcess, c'est la meilleure solution !
208
219## SysUtils.ExecuteProcess
2210
23-La manière la plus simple si vous n'avez pas besoin de pipes ou toute forme de contrôle est d'utiliser simplement SysUtils.ExecuteProcess('/full/path/to/binary',['arg1','arg2']);
11+La manière la plus simple si vous n'avez pas besoin de pipes ou toute forme de contrôle est d'utiliser simplement SysUtils.ExecuteProcess('/full/path/to/binary',\['arg1','arg2'\]);
2412
2513## TProcess
2614
27-Vous pouvez utiliser TProcess pour lancer un programme externe à votre application. Le principal intérêt d'utiliser TProcess est qu'il est :
15+Vous pouvez utiliser TProcess pour lancer un programme externe à votre application. Le principal intérêt d'utiliser TProcess est qu'il est :
2816
29- * Indépendant de la plateforme
30- * Capable de lire les entrées sorties standards (stdin, stdout).
17+- Indépendant de la plateforme
18+- Capable de lire les entrées sorties standards (stdin, stdout).
3119
3220### Un exemple simple
33-```
34-// This is a demo program that shows how to launch
35- // an external program.
36- program launchprogram;
37-
38- // Here we include files that have useful functions
39- // and procedures we will need.
40- uses
41- Classes, SysUtils, Process;
42-
43- // This is defining the var "AProcess" as a variable
44- // of the type "TProcess"
45- var
46- AProcess: TProcess;
47-
48- // This is where our program starts to run
49- begin
50- // Now we will create the TProcess object, and
51- // assign it to the var AProcess.
52- AProcess := TProcess.Create(nil);
53-
54- // Tell the new AProcess what the command to execute is.
55- // Let's use the FreePascal compiler
56- AProcess.CommandLine := 'ppc386 -h';
57-
58- // We will define an option for when the program
59- // is run. This option will make sure that our program
60- // does not continue until the program we will launch
61- // has stopped running. vvvvvvvvvvvvvv
62- AProcess.Options := AProcess.Options + [poWaitOnExit];
63-
64- // Now that AProcess knows what the commandline is
65- // we will run it.
66- AProcess.Execute;
67-
68- // This is not reached until ppc386 stops running.
69- AProcess.Free;
70- end.
21+
22+``` pascal
23+ // This is a demo program that shows how to launch
24+ // an external program.
25+ program launchprogram;
26+
27+ // Here we include files that have useful functions
28+ // and procedures we will need.
29+ uses
30+ Classes, SysUtils, Process;
31+
32+ // This is defining the var "AProcess" as a variable
33+ // of the type "TProcess"
34+ var
35+ AProcess: TProcess;
36+
37+ // This is where our program starts to run
38+ begin
39+ // Now we will create the TProcess object, and
40+ // assign it to the var AProcess.
41+ AProcess := TProcess.Create(nil);
42+
43+ // Tell the new AProcess what the command to execute is.
44+ // Let's use the FreePascal compiler
45+ AProcess.CommandLine := 'ppc386 -h';
46+
47+ // We will define an option for when the program
48+ // is run. This option will make sure that our program
49+ // does not continue until the program we will launch
50+ // has stopped running. vvvvvvvvvvvvvv
51+ AProcess.Options := AProcess.Options + [poWaitOnExit];
52+
53+ // Now that AProcess knows what the commandline is
54+ // we will run it.
55+ AProcess.Execute;
56+
57+ // This is not reached until ppc386 stops running.
58+ AProcess.Free;
59+ end.
7160```
7261
73-C'est tout ! Vous venez d'apprendre à lancer un programme externe depuis votre application.
62+C'est tout ! Vous venez d'apprendre à lancer un programme externe depuis votre application.
7463
7564### Un exemple amélioré
7665
77-C'est bien gentil tout ça, mais comment puis je lire la sortie d'un programme que je viens de lancer ?
66+C'est bien gentil tout ça, mais comment puis je lire la sortie d'un programme que je viens de lancer ?
7867
79-Bien, étendons juste un peu notre exemple :
80-```
81-// Ceci est un programme de démonstration qui montre
82- // comment lancer un programme externe et lire sa sortie
83- program launchprogram;
84-
85- // Ici on inclue les fichiers qui ont les fonctions et procédures
86- // dont nous avons besoin
87- uses
88- Classes, SysUtils, Process;
89-
90- // Ceci définit la variable "AProcess" comment variable
91- // de type "TProcess". On ajoute aussi une TStringList
92- // pour stocker les données de la sortie programme.
93- var
94- AProcess: TProcess;
95- AStringList: TStringList;
96-
97- // Le programme commence ici.
98- begin
99- // On créé l'objet TProcess,
100- // et on l'assigne à la variable AProcess
101- AProcess := TProcess.Create(nil);
102-
103- // On créé l'objet TStringList
104- AStringList := TStringList.Create;
105-
106- // On dit au nouveau AProcess quelle est la commande à exécuter
107- // Utilisons le compilateur de FreePascal
108- AProcess.CommandLine := 'ppc386 -h';
109-
110- // Définissons une option pour indiquer que le programme est lancé.
111- // Cela assurera que notre programme n'attend pas que le programme lancé soit terminé.
112- // Nous allons aussi lui dire que nous voulons lire la sortie du fichier.
113- AProcess.Options := AProcess.Options + [poWaitOnExit, poUsePipes];
114-
115- // Maintenent que AProcess sait quelle ligne de commande il doit lancer, go!
116- AProcess.Execute;
117-
118- // Le programme ne va pas plus loin tant que ppc386 n'a pas fini.
119-
120- // Maintenant on lit dans la TStringList la sortie du programme.
121- AStringList.LoadFromStream(AProcess.Output);
122-
123- // Sauvegarde de la sortie dans un fichier
124- AStringList.SaveToFile('output.txt');
125-
126- // Maintenant on peut vider la TStringList et le TProcess.
127- AStringList.Free;
128- AProcess.Free;
129- end.
68+Bien, étendons juste un peu notre exemple :
69+
70+``` pascal
71+ // Ceci est un programme de démonstration qui montre
72+ // comment lancer un programme externe et lire sa sortie
73+ program launchprogram;
74+
75+ // Ici on inclue les fichiers qui ont les fonctions et procédures
76+ // dont nous avons besoin
77+ uses
78+ Classes, SysUtils, Process;
79+
80+ // Ceci définit la variable "AProcess" comment variable
81+ // de type "TProcess". On ajoute aussi une TStringList
82+ // pour stocker les données de la sortie programme.
83+ var
84+ AProcess: TProcess;
85+ AStringList: TStringList;
86+
87+ // Le programme commence ici.
88+ begin
89+ // On créé l'objet TProcess,
90+ // et on l'assigne à la variable AProcess
91+ AProcess := TProcess.Create(nil);
92+
93+ // On créé l'objet TStringList
94+ AStringList := TStringList.Create;
95+
96+ // On dit au nouveau AProcess quelle est la commande à exécuter
97+ // Utilisons le compilateur de FreePascal
98+ AProcess.CommandLine := 'ppc386 -h';
99+
100+ // Définissons une option pour indiquer que le programme est lancé.
101+ // Cela assurera que notre programme n'attend pas que le programme lancé soit terminé.
102+ // Nous allons aussi lui dire que nous voulons lire la sortie du fichier.
103+ AProcess.Options := AProcess.Options + [poWaitOnExit, poUsePipes];
104+
105+ // Maintenent que AProcess sait quelle ligne de commande il doit lancer, go!
106+ AProcess.Execute;
107+
108+ // Le programme ne va pas plus loin tant que ppc386 n'a pas fini.
109+
110+ // Maintenant on lit dans la TStringList la sortie du programme.
111+ AStringList.LoadFromStream(AProcess.Output);
112+
113+ // Sauvegarde de la sortie dans un fichier
114+ AStringList.SaveToFile('output.txt');
115+
116+ // Maintenant on peut vider la TStringList et le TProcess.
117+ AStringList.Free;
118+ AProcess.Free;
119+ end.
130120```
131121
132122### Lire une grosse sortie
133123
134-Dans l'exemple précédent, nous attendons que le programme se termine. Au moment de la lecture, le programme à écrit sur la sortie. Mais supposons que le programme écrive beaucoup d'informations en sortie, le canal se saturera et nécessitera une lecture. Mais le programme appelant ne peu rien lire tant que le programme appelé n'est pas terminé. Une étreinte mortelle (deadlock) se produit alors.
124+Dans l'exemple précédent, nous attendons que le programme se termine. Au moment de la lecture, le programme à écrit sur la sortie. Mais supposons que le programme écrive beaucoup d'informations en sortie, le canal se saturera et nécessitera une lecture. Mais le programme appelant ne peu rien lire tant que le programme appelé n'est pas terminé. Une étreinte mortelle (deadlock) se produit alors.
135125
136-Le programme suivant, bien que n'utilisant pas poWaitOnExit, lit tout de même la sortie, tant que le programme est ouvert. La sortie est stockée dans un flux de mémoire, et peut être utilisé plus tard pour lire la sortie dans un TStringList.
137-```
138-program procoutlarge;
139- {
140- Copyright (c) 2004 by Marc Weustink
141-
142- This example is creeated in the hope that it will be useful,
143- but WITHOUT ANY WARRANTY; without even the implied warranty of
144- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
145- }
146-
147- uses
148- Classes, Process, SysUtils;
149-
150- const
151- READ_BYTES = 2048;
152-
153- var
154- S: TStringList;
155- M: TMemoryStream;
156- P: TProcess;
157- n: LongInt;
158- BytesRead: LongInt;
159-
160- begin
161- // We cannot use poWaitOnExit here since we don't
162- // know the size of the output. On Linux the size of the
163- // output pipe is 2 kB. If the output data is more, we
164- // need to read the data. This isn't possible since we are
165- // waiting. So we get a deadlock here.
166- //
167- // A temp Memorystream is used to buffer the output
168-
169- M := TMemoryStream.Create;
170- BytesRead := 0;
126+Le programme suivant, bien que n'utilisant pas poWaitOnExit, lit tout de même la sortie, tant que le programme est ouvert. La sortie est stockée dans un flux de mémoire, et peut être utilisé plus tard pour lire la sortie dans un TStringList.
127+
128+``` pascal
129+ program procoutlarge;
130+ {
131+ Copyright (c) 2004 by Marc Weustink
132+
133+ This example is creeated in the hope that it will be useful,
134+ but WITHOUT ANY WARRANTY; without even the implied warranty of
135+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
136+ }
137+
138+ uses
139+ Classes, Process, SysUtils;
140+
141+ const
142+ READ_BYTES = 2048;
143+
144+ var
145+ S: TStringList;
146+ M: TMemoryStream;
147+ P: TProcess;
148+ n: LongInt;
149+ BytesRead: LongInt;
150+
151+ begin
152+ // We cannot use poWaitOnExit here since we don't
153+ // know the size of the output. On Linux the size of the
154+ // output pipe is 2 kB. If the output data is more, we
155+ // need to read the data. This isn't possible since we are
156+ // waiting. So we get a deadlock here.
157+ //
158+ // A temp Memorystream is used to buffer the output
159+
160+ M := TMemoryStream.Create;
161+ BytesRead := 0;
162+
163+ P := TProcess.Create(nil);
164+ P.CommandLine := 'ppc386 -va bogus.pp';
165+ P.Options := [poUsePipes];
166+ WriteLn('-- executing --');
167+ P.Execute;
168+ while P.Running do
169+ begin
170+ // make sure we have room
171+ M.SetSize(BytesRead + READ_BYTES);
171172
172- P := TProcess.Create(nil);
173- P.CommandLine := 'ppc386 -va bogus.pp';
174- P.Options := [poUsePipes];
175- WriteLn('-- executing --');
176- P.Execute;
177- while P.Running do
178- begin
179- // make sure we have room
180- M.SetSize(BytesRead + READ_BYTES);
181-
182- // try reading it
183- n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
184- if n > 0
185- then begin
186- Inc(BytesRead, n);
187- Write('.')
188- end
189- else begin
190- // no data, wait 100 ms
191- Sleep(100);
192- end;
193- end;
194- // read last part
195- repeat
196- // make sure we have room
197- M.SetSize(BytesRead + READ_BYTES);
198- // try reading it
199- n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
200- if n > 0
201- then begin
202- Inc(BytesRead, n);
203- Write('.');
204- end;
205- until n <= 0;
206- if BytesRead > 0 then WriteLn;
207- M.SetSize(BytesRead);
208- WriteLn('-- executed --');
209-
210- S := TStringList.Create;
211- S.LoadFromStream(M);
212- WriteLn('-- linecount = ', S.Count, ' --');
213- for n := 0 to S.Count - 1 do
214- begin
215- WriteLn('| ', S[n]);
216- end;
217- WriteLn('-- end --');
218- S.Free;
219- P.Free;
220- M.Free;
221- end.
173+ // try reading it
174+ n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
175+ if n > 0
176+ then begin
177+ Inc(BytesRead, n);
178+ Write('.')
179+ end
180+ else begin
181+ // no data, wait 100 ms
182+ Sleep(100);
183+ end;
184+ end;
185+ // read last part
186+ repeat
187+ // make sure we have room
188+ M.SetSize(BytesRead + READ_BYTES);
189+ // try reading it
190+ n := P.Output.Read((M.Memory + BytesRead)^, READ_BYTES);
191+ if n > 0
192+ then begin
193+ Inc(BytesRead, n);
194+ Write('.');
195+ end;
196+ until n <= 0;
197+ if BytesRead > 0 then WriteLn;
198+ M.SetSize(BytesRead);
199+ WriteLn('-- executed --');
200+
201+ S := TStringList.Create;
202+ S.LoadFromStream(M);
203+ WriteLn('-- linecount = ', S.Count, ' --');
204+ for n := 0 to S.Count - 1 do
205+ begin
206+ WriteLn('| ', S[n]);
207+ end;
208+ WriteLn('-- end --');
209+ S.Free;
210+ P.Free;
211+ M.Free;
212+ end.
222213```
223214
224215### Employer l'entrée et la sortie d'un TProcess
225216
226-Voir l'exemple processdemo dans le [dépôt SVN de Lazarus-CCR ](<https://svn.sourceforge.net/svnroot/lazarus-ccr/examples/process>).
217+Voir l'exemple processdemo dans le [dépôt SVN de Lazarus-CCR](https://svn.sourceforge.net/svnroot/lazarus-ccr/examples/process).
227218
228219### Remarque sur l'utilisation de TProcess
229220
230-Si vous programmez une application multi-plateforme, vous pouvez changer la ligne de commande appelant l'application, en fonction du système d'exploitation. Pour cela utilisez {$IFDEF} et {$ENDIF}.
221+Si vous programmez une application multi-plateforme, vous pouvez changer la ligne de commande appelant l'application, en fonction du système d'exploitation. Pour cela utilisez {\$IFDEF} et {\$ENDIF}.
231222
232-Exemple :
233-```
234-{...}
235- AProcess:TProcess.Create(nil)
236- {$IFDEF WIN32}
237- AProcess.CommandLine := 'calc.exe'; //Windows Calc
238- {$ENDIF}
239- {$IFDEF LINUX}
240- AProcess.CommandLine := 'kcalc'; //KDE Calc
241- {$ENDIF}
242- AProcess.Execute; //in alternative, you can use AProcess.Active:=True
243- {...}
223+Exemple :
224+
225+``` pascal
226+ {...}
227+ AProcess:TProcess.Create(nil)
228+ {$IFDEF WIN32}
229+ AProcess.CommandLine := 'calc.exe'; //Windows Calc
230+ {$ENDIF}
231+ {$IFDEF LINUX}
232+ AProcess.CommandLine := 'kcalc'; //KDE Calc
233+ {$ENDIF}
234+ AProcess.Execute; //in alternative, you can use AProcess.Active:=True
235+ {...}
244236```
245237
246238### Exemple de "Dialogue" avec le processus aspell
247239
248-Dans le code source de pasdoc [pasdoc](<http://pasdoc.sourceforge.net/>) vous trouverez deux unités qui analysent du texte par "dialogue" en lançant un processus aspell au travers de canaux :
240+Dans le code source de pasdoc [pasdoc](http://pasdoc.sourceforge.net/) vous trouverez deux unités qui analysent du texte par "dialogue" en lançant un processus aspell au travers de canaux :
249241
250- * [PasDoc_ProcessLineTalk.pas unit](<http://cvs.sourceforge.net/viewcvs.py/*checkout*/pasdoc/pasdoc/source/component/PasDoc_ProcessLineTalk.pas>) implémente la classe TProcessLineTalk, descendante de TProcess, qui permet un dialogue facile entre n'importe quel processus sur le principe du ligne par ligne.
242+- [PasDoc_ProcessLineTalk.pas unit](http://cvs.sourceforge.net/viewcvs.py/*checkout*/pasdoc/pasdoc/source/component/PasDoc_ProcessLineTalk.pas) implémente la classe TProcessLineTalk, descendante de TProcess, qui permet un dialogue facile entre n'importe quel processus sur le principe du ligne par ligne.
251243
252- * [PasDoc_Aspell.pas units](<http://cvs.sourceforge.net/viewcvs.py/*checkout*/pasdoc/pasdoc/source/component/PasDoc_Aspell.pas>) implémente la classe de TAspellProcess, qui permet d'analyser du texte en utilisant l'exemple de TProcessLineTalk pour exécuter aspell et communiquer avec le processus en cours d'exécution d'aspell.
244+- [PasDoc_Aspell.pas units](http://cvs.sourceforge.net/viewcvs.py/*checkout*/pasdoc/pasdoc/source/component/PasDoc_Aspell.pas) implémente la classe de TAspellProcess, qui permet d'analyser du texte en utilisant l'exemple de TProcessLineTalk pour exécuter aspell et communiquer avec le processus en cours d'exécution d'aspell.
253245
254246Ces deux unités sont plutôt indépendantes du reste des sources de pasdoc, par conséquent elles peuvent servir d'exemples d'utilisation de TProcess en situation réelle pour exécuter et communiquer par les canaux avec un autre programme.
255247
256248---
257-*From the Free Pascal wiki, page "Executing External Programs/fr", as the Internet Archive kept it on 2023-03-22. 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).*
249+*From the Free Pascal wiki, page "Executing External Programs/fr", 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