IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Sommaire > Système > Process
        Comment lancer un processus ?
        Comment arrêter un processus ?
        Comment piloter un programme console externe?
        Comment créer un programme console PIPE en redirigeant la sortie standard ?
        Comment rediriger la sortie standard d'un processus vers un composant ?
        Comment lister les processus en cours d'exécution ?

        


Comment lancer un processus ?
auteurs : abelman, freegreg, Laurent Dardenne
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é.

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 :

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 est devient :

... 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 :

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;
lien :  System.Diagnostics.Process
lien :  Exécution synchrone d'un programme console dans une application C#
lien :  Comment arrêter un processus ?

Comment arrêter un processus ?
auteurs : abelman, Laurent Dardenne
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 utilsé 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ée (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.

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;
lien :  System.Diagnostics.Process
lien :  Comment lancer un processus ?

Comment piloter un programme console externe?
auteur : Laurent Dardenne
Il est possible de réorganiser les entrées/sorties standards entre 2 applications. L'application principale gérant les entrées/sorties d'un 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 prg externe en connectant la sortie standard ( CON /écran) sur l'entrée du programme externe et l'entrée standard ( CON /Clavier ) 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.

< ! [CDATA[ 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.
lien :  System.Diagnostics.Process
lien :  Comment créer un programme console PIPE en redirigeant la sortie standard ?

Comment créer un programme console PIPE en redirigeant la sortie standard ?
auteur : Laurent Dardenne
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 construitent 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 :

 type upper.dpr|upper.exe
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 :

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.
lien :  System.Diagnostics.Process

Comment rediriger la sortie standard d'un processus vers un composant ?
auteurs : abelman, Laurent Dardenne
Il est possible de rediriger la sortie standard d'un processus et de l'afficher dans un TextBox multiligne par exemple.

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 ;

Comment lister les processus en cours d'exécution ?
auteurs : abelman, bodbod, Laurent Dardenne
Pour lister les processus en cours on utilise la méthode GetProcesses de la classe System.Diagnostics.Process.

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.
lien :  System.Diagnostics.Process

        

Consultez les autres F.A.Q's

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 © 2005 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site ni 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.