FAQ Delphi .NETConsultez toutes les FAQ

Nombre d'auteurs : 15, nombre de questions : 54, dernière mise à jour : 30 mars 2017 

 
OuvrirSommaireSystèmeProcess

Pour lancer un processus depuis notre application, on utilise la classe System.Diagnostics.Process.
Dans cette solution on ne mémorise pas une instance de la classe Process mais uniquement l'ID du processus exécuté.

 
Sélectionnez

					Function StartProcess(FName,Arguments :String):Integer;
					// Nécessite l'ajout de l'unité System.Diagnostics dans la clause uses.
					var MonProcessus : System.Diagnostics.Process ;
					begin
					If FName<>'' then
					begin
					// Instance de la classe Process
					MonProcessus := System.Diagnostics.Process.Create;
					With MonProcessus do
					begin
					// Nom de l'executable à lancer
					StartInfo.FileName:=FName;

					// Arguments à passer à l'exécutable à lancer
					StartInfo.Arguments:=Arguments;

					// Démarrage du processus
					Start;

					// Récupére l'ID unique du process
					Result:=ID;

					// On libère les ressources dont on n'a plus besoin.
					Close; // Attention Close ne met pas fin au processus.
					end;
					end
					else Result:= -1;
					end;
				

Exemple d'appel :

 
Sélectionnez

					var ProcessID : Integer;
					begin
					ProcessID:=StartProcess('Notepad.exe','C:\Windows\System.ini');
					...
				

Si vous souhaitez être averti de l'arrêt d'un de vos processus, vous devez renseigner le délégué Process.Exited et positionner la propriété Process.EnableRaisingEvents à True.

Dans ce cas le code précédent devient :

 
Sélectionnez

					...
					With MonProcessus do
					begin
					// Nom de l'executable à lancer
					StartInfo.FileName:=FName;
					// Arguments à passer à l'exécutable à lancer
					StartInfo.Arguments:=Arguments;

					// La propriété EnableRaisingEvents indique si le composant doit être averti en cas d'arrêt
					// d'un processus par le système d'exploitation.
					// Elle est utilisée lors du traitement asynchrone pour avertir votre application qu'un processus
					// n'est plus exécuté.
					EnableRaisingEvents:=True;

					// Renseigne le délégué de fin de process
					Include(Exited ,@FinProcess);

					// Démarrage du processus
					...
				

La procédure référencée étant :

 
Sélectionnez

					procedure FinProcess(Sender: System.Object; AArgs: System.EventArgs);
					// Procédure appelée lors de la fin d'exécution d'un programme externe
					begin
					Writeln('Code de fin du processus : '+(Sender as System.Diagnostics.Process).ExitCode.ToString);
					Writeln('Appuyez sur une touche pour terminer.');
					end;
				
Mis à jour le 25 avril 2005  par abelman, freegreg, Laurent Dardenne

Lien : System.Diagnostics.Process
Lien : Exécution synchrone d'un programme console dans une application C#
Lien : Comment arrêter un processus ?

Pour arrêter un processus, il faut soit disposer d'un objet System.Diagnostics.Process qui représente le processus soit un ID de processus qui permet de récupérer une instance de la classe Process.

La méthode utilisée pour arrêter un processus est différente selon qu'il s'agit d'une application console ou fenêtrée.

Pour les applications fenêtrées (WinForm / VCL) il est préférable d'utiliser la méthode CloseMainWindow afin que l'application reçoive le message d'arrêt et se termine correctement. Si l'appel échoue, on peut alors forcer l'arrêt avec la méthode Kill.
Ce dernier point n'est pas mis en oeuvre dans cette solution.

 
Sélectionnez

					Procedure KillProcess(ProcessID : Integer);
					// Nécessite l'ajout de l'unité de System.Diagnostics dans la clause uses.
					var MonProcessus : System.Diagnostics.Process ;

					begin
					// Voir "Comment lancer un processus ?"
					Readln;
					try
					// Récupére une instance d'un Processus à partir d'un ID
					MonProcessus:=System.Diagnostics.Process.GetProcessById(ProcessID);

					// Obtient le Handle de la fenêtre principale
					// Pour terminer le processus
					if MonProcessus.MainWindowHandle<>0
					// Pour un programme fenêtré
					then MonProcessus.CloseMainWindow
					// Pour un programme console, c'est la seule possibilité.
					else MonProcessus.Kill;
					// On libère les ressources dont on n'a plus besoin.
					MonProcessus.Close;
					except
					on System.ArgumentException do
					Writeln('Erreur le processus '+IntToStr(ProcessID)+' n''existe pas !');
					end;
					end;
				
Créé le 11 avril 2013  par abelman, Laurent Dardenne

Lien : System.Diagnostics.Process
Lien : Comment lancer un processus

Il est possible de réorganiser les entrées/sorties standards entre 2 applications. L'application principale gérant les entrées/sorties d'une application secondaire externe.

L'exemple suivant est suffisament documenté pour en comprendre le fonctionnement.

Le principe :
on redirige l'entrée et la sortie standard avec ceux du programme externe en connectant la sortie standard ( CON /écran) de l'application principale sur l'entrée du programme externe et l'entrée standard ( CON /Clavier ) de l'application principale sur la sortie du programme externe.

On peut ainsi, de l'application courante, envoyer des informations vers le programme externe et en recevoir à partir de ce même programme externe.

 
Sélectionnez

					program Batch;
					{$APPTYPE CONSOLE}
					// Pilote un prg externe

					uses
					System.Diagnostics,
					System.IO; //StreamWriter

					var MyProcess : System.Diagnostics.Process ;
					ProcessInformation : System.Diagnostics.ProcessStartInfo;
					Chaine: String;

					begin
					ProcessInformation:=System.Diagnostics.ProcessStartInfo.Create;
					With ProcessInformation do
					begin
					// On désactive le shell
					// permet de rediriger les flux d'entrée, de sortie et d'erreur.
					// Dans ce cas 'WorkingDirectory' n'est pas utilisé
					UseShellExecute := False;

					// On redirige la sortie standard du programme externe
					// Permet d'écrire à un emplacement autre que le flux de sortie standard (généralement l'écran du moniteur).
					// Utilisé pour écrire des données dans un fichier, par exemple.
					RedirectStandardOutput := True;
					// On redirige l'entrée standard du programme externe

					//permet de lire à partir d'une source autre que le flux d'entrée standard (généralement le clavier).
					//Utilisé pour lire des données dans un fichier, par exemple.
					RedirectStandardInput := True;

					// si UseShellExecute := False : On définit le programme à exécuter
					FileName := 'C:\Windows\System32\Debug.exe';
					end;

					MyProcess := System.Diagnostics.Process.Create;

					With MyProcess do
					begin
					StartInfo:=ProcessInformation;
					// Exécute le programme externe
					Start;
					(*
					Prg principale         prg externe
					--------             ---------
					|      |IN        IN |       |
					|      |<--\    /--> |       |
					|      |    \  /     |       |
					|      |     \/      |       |
					|      |OUT  /\  OUT |       |
					|      |--> /  \ <-- |       |
					--------             ---------

					Dans le prg principale :
					on écrit vers OUT
					on lit à partir de IN
					*)

					//Redirige l'entrée et la sortie standard avec ceux du prg externe
					// Connecte la sortie standard ( CON /écran) sur l'entrée du programme externe
					// On peut donc, via Writeline, entrer une saisie destinée au programme externe
					System.Console.SetOut(MyProcess.StandardInput);

					// Connecte l'entrée standard ( CON /Clavier ) sur la sortie du programme externe
					// On peut donc, via Readline, lire un résultat provenant du programme externe
					System.Console.SetIn(MyProcess.StandardOutput);

					Close;
					end;
					// Envoie 3 commande au prg externe, ici DEBUG,
					// ? : demande d'afficher l'aide
					// D : demande un dump (128 octets)
					// Q : Quitte et termine l'application externe
					System.Console.Out.Writeline('?'+#10#13+'D'+#10#13+'Q');

					// Lit le résultat affiché par DEBUG
					// Lecture en une seule fois
					//Chaine:=System.Console.In.ReadToEnd;

					// Lecture ligne par ligne
					Chaine:=''; // Nécessaire sinon la variable 'Chaîne' n'est pas instancié !

					While Assigned(Chaine) do
					begin
					Chaine:=System.Console.In.ReadLine;
					// Ecrit sur la sortie standard TextOutput
					// Si on remplace par Console.WriteLine(Chaine) le comportement est différent !
					WriteLn(chaine); // Est égale à TextOutput.Writeln. Cf IL-Dasm
					end;
					//Restaure les valeurs par défaut
					//Pas nécessaire de mémoriser les valeurs, on récrée un objet.
					// Sous Delphi c'est redondant cf. TextOutput...
					System.Console.SetOut(StreamWriter.Create(System.Console.OpenStandardOutput));
					System.Console.SetIn(StreamReader.Create(System.Console.OpenStandardInput));

					readln;
					end.
				
Créé le 11 avril 2013  par Laurent Dardenne

Lien : System.Diagnostics.Process
Lien : Comment créer un programme console PIPE en redirigeant la sortie standard ?

Pour manipuler les entrées/sorties standard de l'application courante, il est préférable de ne plus utiliser les fonctions assign, reset, etc. (voir la FAQ Delphi Win32), bien qu'elles soient présentes à des fins de compatibilité.

On peut utiliser les classes TextInput,TextOutput et TextErrOutput.
Ces classes permettent de manipuler aisément les handles des entrées/sorties standard.
Elles sont de type Text, les instances sont construites par défaut via un constructeur de classe et sont référencées dans l'unité System.pas.
Ces instances, étant construites avant tout autres objets de l'application, référencent toujours les entrées-sorties de la console d'origine.

Je différencie donc ici la manipulation des entrées/sorties standard de l'application courante de celle d'une application externe exécutée à partir de l'application courante.

La solution proposée ici se teste dans une console avec :

 
Sélectionnez

					type upper.dpr|upper.exe
				
 
Sélectionnez

					program upper;
					{$APPTYPE CONSOLE}
					// Redirection de type 'PIPE', comportement similaire au programme FIND.EXE ou SORT.EXE
					// Renvoie une chaîne reçue en entrée (input) en majuscule sur la sortie (output)

					Var Chaine: String;

					Begin
					{ TextInput et TextOutPut sont construit autour de la classe :
					Text = class
					Mode: Word;
					Flags: Word;
					Factory: ITextDeviceFactory;
					Reader: System.IO.TextReader;
					Writer: System.IO.TextWriter;
					Filename: string;
					...
					}
					While not(Eof) Do
					Begin
					// TextInput   { Entrée standard }
					// TextInput.Intput=Text
					// TextInput.Input.Reader := System.Console.In;
					Readln(TextInput.Input,Chaine);  // Lit sur l'entrée standard

					// TextOutput  { Sortie standard}
					// TextInput.Output=Text
					// TextInput.Output.Writer := System.Console.Out;
					Writeln(TextOutput.OutPut,chaine.ToUpper); // Ecrit sur la sortie standard

					// Erreur standard :
					//  TextErrOutput.ErrOutput := Text
					//  TextErrOutput.ErrOutput.Writer := System.Console.Error;
					end;
					end.
				

La version simplifiée :

 
Sélectionnez

					program upper2;
					{$APPTYPE CONSOLE}
					// Redirection de type 'PIPE', comportement similaire au programme FIND.EXE ou SORT.EXE
					// Renvoie une chaîne reçue en entrée (input) en majuscule sur la sortie (output)

					Var Chaine: String;

					Begin
					While not(Eof) Do
					Begin
					Readln(Chaine);  // Lit sur l'entrée standard
					Writeln(chaine.ToUpper); // Ecrit sur la sortie standard
					end;
					end.
				
Créé le 20 mai 2005  par Laurent Dardenne

Lien : System.Diagnostics.Process

Il est possible de rediriger la sortie standard d'un processus et de l'afficher dans un TextBox multiligne par exemple.

 
Sélectionnez

					procedure TWinForm.RedirectStdOutput;
					var proc : System.Diagnostics.Process ;
					output : String ;
					begin
					proc:=System.Diagnostics.Process.Create;
					// On désactive le shell
					proc.StartInfo.UseShellExecute:=false;
					// On redirige la sortie standard
					proc.StartInfo.RedirectStandardOutput:=true;
					// On définit la commande
					proc.StartInfo.FileName:='EditeurFAQ.exe';
					// Démarrage de la commande
					proc.Start;
					// Lecture de la sortie de la commande
					output:=proc.StandardOutput.ReadToEnd;
					Console.WriteLine(output);
					// Attente de la fin de la commande
					proc.WaitForExit;
					// Libération des ressources
					proc.Close;
					end ;
				
Créé le 20 mai 2005  par abelman, Laurent Dardenne

Pour lister les processus en cours on utilise la méthode GetProcesses de la classe System.Diagnostics.Process.

 
Sélectionnez

					uses
					SysUtils,
					System.Diagnostics;

					var AllProcess : array of System.Diagnostics.Process ;
					prc : System.Diagnostics.Process;

					begin
					// Pour tous les processus en cours sur l'ordinateur local
					AllProcess:= Process.GetProcesses ;
					For prc in AllProcess do
					Writeln(Prc.ProcessName);

					Writeln;

					// Pour tous les processus notepad en cours sur l'ordinateur local
					AllProcess := Process.GetProcessesByName('svchost') ;
					If length(AllProcess)>0 then
					For prc in AllProcess do
					With prc do
					Writeln(ProcessName+'. Mémoire allouée:'+PrivateMemorySize.ToString);
					end.
				
Mis à jour le 25 avril 2005  par abelman, bodbod, Laurent Dardenne

Lien : System.Diagnostics.Process

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2009 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.