Les processus
Un article de Mangue.org, l'encyclopéde libre.
Un processus, est un "conteneur" dans lequel peuvent s'exécuter plusieurs domaines d'application.
Pour manipuler les processus, le framework .NET nous fournit la classe Process. (namespace System.Diagnostics) Cette classe permet de démarrer, de stopper, de contrôler et de surveiller les processus. Par exemple, on peut obtenir une liste des processus qui tournent, ou démarrer un nouveau processus. De même, c'est cette classe qui est utilisée pour accéder aux processus sytème. On peut également obtenir des informations sur un processus en particulier, comme par exemple quels sont les threads qui y tournent, quels sont les modules (dll et exe) chargés en mémoire, le montant de mémoire consommé, etc.
| Sommaire |
Démarrer un processus
Le démarrage d'un processus s'opère via la méthode Start. La classe Process contient quatre versions de cette méthode dont trois statiques. Pour ces trois versions, il n'est pas nécessaire de créer un objet Process, car ce sont ces méthodes qui vont le fournir. La méthode non-statique, au contraire, requiert qu'un objet soit préalablement créé. Nous allons donc nous intéresser au constructeur de la classe Process. Il est très simple: il ne prend aucun paramètre et ne retourne rien.
Process p = new Process()Une fois cet objet créé, nous allons pouvoir appeler la méthode Start. Avant de pouvoir le faire, nous devons renseigner la propriété StartInfo. Elle contient un objet de type ProcessStartInfo, que la méthode va utiliser pour savoir quelle application lancer, et avec quelles options.
Les propriétés de l'objet ProcessStartInfo sont les suivantes:
- string Arguments: cette chaine indique les arguments de ligne de commande à passer au programme
- bool CreateNoWindow: indique si oui ou non le processus est démarré dans une nouvelle fenêtre
- StringDictionnary EnvironmentVariables: contient des chemins de recherche pour des fichiers, répertoires temporaires, options du programme, etc. La classe StringDictionnary est une table de hachage destinée aux chaines de caractère. Elle s'initialise avec un constructeur vide, et fournit une méthode Add( string clé, string valeur) pour ajouter des paires clé/valeur.
- bool ErrorDialog: indique si une boite de dialogue d'erreur doit être affiché en cas d'échec de démarrage du processus. Si cette propriété est à true, UseShellExecute doit l'être aussi.
- IntPtr ErrorDialogParentHandle: indique le handle de la fenêtre parente du dialogue d'erreur qui apparait éventuellement en cas d'échec de démarrage du processus. Cette propriété est utile pour assurer que le dialogue apparaitra bien devant votre application.
- string FileName: contient le nom de l'exécutable à démarrer dans le processus. Il est possible, si UseShellExecute est à true, de passer un nom de fichier, auquel cas l'application associée au type du fichier, s'il existe une association, sera lancée.
- bool RedirectStandardError: indique si les messages d'erreur du processus sont redirigés vers le membre StandardError de l'objet Process associé au processus. (si cette propriété est à true, UseShellExecute ne doit pas l'être)
- bool RedirectStandardInput: indique si l'entrée à partir de laquelle le processus reçoit des commandes (par défaut le clavier) est redirigée vers le membre StandardInput de l'objet Process associé au processus. Cela permet par exemple de lire des commandes à partir d'un fichier. (si cette propriété est à true, UseShellExecute ne doit pas l'être)
- bool RedirectStandardOutput: indique si la sortie standard du processus (par défaut l'écran) est redirigée vers le membre StandardOutput de l'objet Process associé au processus. (si cette propriété est à true, UseShellExecute ne doit pas l'être)
- bool UseShellExecute: indique si le shell du système d'exploitation est utilisé pour démarrer le processus.
- string Verb: indique l'action à accomplir avec le fichier contenu dans FileName lorsque le processus sera démarré. Chaque extension de fichier enregistrée dans le système possède un ensemble de mots. Par exemple, le mot "Print" provoquera l'impression du document FileName, si toutefois il le supporte.
- string[] Verbs:contient la liste de mots associés à l'extension de FileName. L'extension doit donc être présente dans le nom de fichier (c'est à partir d'elle qu'est obtenue la liste de mots) ce qui n'est obligatoire si vous spécifiez directement le mot à l'aide de la propriété Verb.
- ProcessWindowStyle WindowsStyle: spécifie le style de la fenêtre dans laquelle sera démarré le processus. ProcessWindowStyle est une énumération qui peut prendre quatre valeurs: Hidden pour démarrer avec une fenêtre invisible, Maximized pour démarrer avec une fenêtre maximisée, Minimized pour démarrer avec une fenêtre minimisée, et enfin Normal pour démarrer avec une fenêtre ayant la taille et l'emplacement par défaut.
- string WorkingDirectory: indique le répertoire dans lequel le processus sera démarré.
Heureusement, nous n'avons pas à nous occuper de toutes ces propriétés, car seul FileName est indispensable.
Nous pouvons maintenant appeler la méthode Start, qui ne prend aucun paramètre et retourne un booléen. Lors de l'appel de cette méthode, le système vérifie qu'il n'existe pas déjà en mémoire un processus répondant aux spécifications données dans le ProcessStartInfo. Si c'est le cas; aucun nouveau processus ne sera créé, mais le processus existant sera associé à la classe. La méthode retournera dans ce cas la valeur false. Si par contre aucun processus répondant à ces critères n'existe, il en sera créé un nouveau ,et la valeur true sera renvoyée.
Process p = new Process(); p. StartInfo = new ProcessStartInfo(); p.StartInfo.FileName = "notepad.exe"; p.Start();Start peut lever trois types d'exceptions:
- InvalidOperationException: Si aucun nom n'a été spécifié dans le ProcessStartInfo, ou bien si UseShellExecute est à true alors que RedirectStandardInput, RedirectStandardOutput ou RedirectStandardError le sont aussi.
- Win32Exception: en cas d'erreur à l'ouverture de l'application associée au fichier spécifié dans le ProcessStartInfo.
- ObjectDisposedException: si la méthode Dispose a été appelée sur l'objet. Dans ce cas, ses ressources ont été libérées et l'objet est donc inutilisable.
Intéressons-nous à présent aux trois versions statiques de Start.
Une première version de la méthode prend un objet ProcessStartInfo en paramètre, ce qui en fait une copie presque intégrale de la version non-statique. Elle lève les mêmes exceptions, plus ArgumentException, dans le cas où l'un des paramètres est à null. Voici à quoi ressemble le code précédent si on utilise cette méthode:
ProcessStartInfo psi = new ProcessStartInfo(); psi.FileName = "notepad.exe"; Process p = Process.Start(psi);
Les deux autres versions de Start permettent de s'affranchir de l'objet ProcessStartInfo. La première prend un paramètre une string qui contient le nom de l'application à lancer, tandis que la deuxième prend le même premier paramètre, suivi d'une deuxième chaine de caractères qui spécifie les arguments de ligne de commande à passer au programme.
Process p = Process.Start("notepad.exe");
Ces deux versions de la méthode peuvent lever les exceptions suivantes:- ArgumentException: si l'un des paramètres est à null.
- Win32Exception: en cas d'erreur à l'ouverture de l'application associée au fichier spécifié dans le ProcessStartInfo.
- ObjectDisposedException: si la méthode Dispose a été appelée sur l'objet. Dans ce cas, ses ressources ont été libérées et l'objet est donc inutilisable.
Stopper un processus
Nous disposons de deux moyens pour terminer un processus. Parlons tout d'abord de la méthode Kill.
Cette méthode a pour effet de stopper immédiatement le processus associé à l'objet Process. Elle n'accepte aucun paramètre, et ne retourne rien.
La méthode Kill force l'arrêt du processus. Cette méthode brutale empêche donc toute demande de confirmation utilisateur et peut conduire à la perte de données si l'application qui tournait dans le processus était en pleine édition. C'est pourquoi nous vous conseillons de n'utiliser cette méthode qu'en dernier recours.
monProcessus.Kill();Trois types d'exceptions sont susceptibles d'être levés par cette méthode:
- Win32Exception: le processus associé n'a pas pu être terminé.
- SystemException: cette exception peut être levée pour trois raisons. Cela peut être dû au fait que la propriété qui contient l'identifiant du processus est vide, ce qui peut signifier que la handle à partir duquel cet identifiant aurait pu être déterminé n'existe pas. Il est également possible que ce soit parce qu'aucun processus n'est associé à l'objet Process. En dernier cas de figure, cette exception peut être levée si nous essayons de terminer un processus distant. En effet, Kill n'est valable que pour les processus locaux.
- InvalidOperationException: le processus a déjà été terminé.
Pour arrêter proprement un processus, il faut utiliser CloseMainWindow. Quand un processus est en exécution, sa boucle des messages est en attente. Elle ne s'exécutera que quand un message lui sera envoyée par le système d'exploitation. L'appel à CloseMainWindow invalide toutes les boucles de messages qui s'exécutent pour chaque thread du processus et ferme toutes les fenêtres. Cet appel ne fait en réalité qu'envoyer un message de fermeture, et ne force donc pas l'application à s'arrêter. Cela permet par exemple de demander confirmation à l'utilisateur avant de quitter. Il est également possible que l'application refuse de se fermer: dans ce cas, vous pouvez lui forcer la main en utilisant Kill. Un appel à CloseMainWindow produit un effet similaire à ce qui se passe quand un utilisateur ferme lui-même une application.
A la différence de Kill, qui produit un arrêt anormal du processus, CloseMainWindow ferme proprement le processus et toutes ses fenêtres. Cependant, comme certaines applications ne possèdent pas d'interface, et donc pas de fenêtre, la méthode Kill est la seule façon de les arrêter.
La méthode CloseMainWindow n'est valable que pour les processus locaux.
Elle ne prend rien en paramètre, et renvoie un booléen qui est à true si le message de fermeture a correctement été envoyé, et false si le processus associé n'a pas de fenêtre principale ou que celle-ci est désactivée. (par exemple si une boite de dialogue modale est affichée)
monProcessus.CloseMainWindow();
La classe Process comprend également une méthode Close. Elle se contente de libérer les ressources utilisées par l'objet Process. En d'autres termes, elle dissocie le processus de l'objet Process, mais n'arrête en aucun cas le processus. Si le processus associé est terminé, la méthode Close indique au système d'exploitation que le Handle qu'elle contient peut à présent être utilisé pour un autre processus que celui qui était associé à l'objet Process. Bien sûr dans ce cas, on ne pourra plus accéder aux informations concernant le processus, Close doit donc être appelée au dernier moment. Elle ne prend aucun paramètre et ne retourne rien.
monProcessus.Close();
Contrôler un processus
Les processus sont identifiés par leur identifiant de processus. On peut aussi les identifier par un handle, mais il n'est pas garanti qu'il soit unique sur la machine. En effet, ce handle persiste en mémoire même une fois le processus arrêté, ce qui permet de connaitre sont code de sortie (ExitCode) et l'heure a laquelle il s'est arrêté (ExitTime), mais a le désavantage faire qu'un handle n'est pas forcément unique.
Avant de pouvoir contrôler un processus, il doit être associé à notre objet Process. Cela est fait automatiquement lorsqu'on créé un processus via la méthode Start, mais on peut également associer un processus existant.
Nous pouvons par exemple, en uitilisant la méthode GetCurrentProcess, créer un nouvel objet Process et l'associer au processus courant. Cela se fait très simplement:
Process p = Process.GetCurrentProcess();
Comme vous pouvez le voir, cette méthode est statique, et c'est elle qui créé l'objet Process.
Si nous connaissons l'identifiant du processus que nous voulons contrôler, l'utilisation de la méthode GetProcessById s'impose. Elle aussi statique, elle retourne un objet Process. Elle accepte en paramètre un entier qui spécifie l'identifiant, et éventuellement une chaine de caractères qui est le nom de l'ordinateur distant où aller chercher ce processus.
Process p = Process.GetProcessById( monIdentifiant, "odinateur distant" );
La méthode statique GetProcessesByName permet, quant à elle, de récupérer un tableau d'objets Process associés aux processus portant le nom spécifié. Par exemple,
Process[] p = Process.GetProcessesByName("notepad");
va récupérer tous les processus portant le nom "notepad", soit tous les processus dans lesquels s'exécute le bloc-notes.
Il est également possible de réaliser cette opération sur un ordinateur distant, en spécifiant son nom sur le réseau:
Process[] p = Process.GetProcessesByName("notepad", "un ordinateur distant");
Il est possible de récupérer la liste complète des processus sur un ordinateur local ou distant en utilisant la méthode GetProcesses. Elle retourne un tableau d'objets Process:
Process[] pLocal = Process.GetProcesses();
Process[] pDistant = Process.GetProcesses("ordinateur distant");
Certains processus du système s'exécutent dans un mode spécial. Il est impossible d'accéder à ces processus tant que nous n'avons pas appelé la méthode EnterDebugMode. Une fois les opérations sur le processus spécial terminées, on peut quitter le mode spécial en appelant LeaveDebugMode.
Soit un objet Process p:
p.EnterDebugMode(); // association du processus spécial.... p.LeaveDebugMode();Il peut parfois être utile de stopper l'exécution de son programme le temps qu'un processus se termine. Cela permet par exemple d'éviter les exceptions lorsqu'on essaye d'accéder aux propriétés ExitTime et ExitCode.
La méthode WaitForExit permet d'effectuer cet opération. Cela peut cependant conduire votre application à se bloquer. En effet, si par exemple nous appelons CloseMainWindow sur un processus qui a été écrit pour ne jamais entrer dans la boucle des messages, puis WaitForExit pour attendre qu'il se termine, l'application va se bloquer car le processus que nous voulions terminer ne traitera pas le message de sortie reçu.
Une fois le processus terminé, nous pouvons accéder à certaines informations, comme ExitTime et ExitCode. Cela est possible grâce au handle, qui permet d'accéder aux informations via le système d'exploitation. Une fois que nous n'avons plus besoin des ces informations, il convient de libérer le handle par un appel à Close.
La version de base de WaitForExit ne prend aucun paramètre et ne retourne rien. Un autre version accepte en unique paramètre un int qui définit le nombre de millisecondes à attendre que le processus se termine. Elle retourne un booléen qui indique si le processus s'est terminé dans le délai imposé ou non.
Les deux versions de la méthodes retournent les mêmes exceptions:
- Win32Exception: si l'accès au paramètre d'attente est impossible
- SystemException: si aucun Id de processus n'est renseigné, et que le Handle est inexistant, ou si aucun processus n'est associé, ou encore si la méthode est appelée sur un processus distant.
if( !monProcessus.WaitForExit(5000) )
Console.Write("le processus ne s'est pas
terminé dans les 5 secondes");
Nous avons également à notre disposition la méthode WaitForInputIdle, qui permet de stopper notre programme le temps que le processus associé soit dans un état appelé "idle". Cela ne concerne que les processus avec une interface utilisateur. Un processus atteint cet état lorsque l'application n'a aucun message à traiter dans sa boucle des messages, et attend donc le prochain message. Attendre cet état peut être intéressant quand, par exemple, vous voulez attendre que votre application aie fini de créer sa fenêtre principale pour communiquer avec elle. La méthode retourne true si le processus a atteint l'état idle, false sinon. De même, si cette méthode est appelée sur un processus qui n'a pas d'interface utilisateur, elle retourne toujours false. Attention, cette méthode peut bloquer votre programme si vous l'appelez sur un processus qui est écrit de façon à toujours sortir de la boucle des messages immédiatement après que le travail y soit terminé.
Une autre version de la méthode accepte un int en paramètre. Ce nombre détermine le nombre de millisecondes à attendre que le processus devienne idle. S'il le devient dans le temps imparti, la méthode retourne true, false sinon.
Le code précédent chronomètre à l'aide de cette méthode le temps de lancement de Word.
// récupération de l'heure courant
DateTime debut = new DateTime(DateTime.Now.Ticks);
// lancement du processus
Process p = Process.Start("winword.exe");
// on attend qu'il termine son chargement
p.WaitForInputIdle();
// on reprend l'heure courante
DateTime fin = new DateTime(DateTime.Now.Ticks);
// soustraction de l'heure de départ à l'heure de fin
TimeSpan ts = fin.Subtract(debut);
// affichage du résultat
Console.WriteLine("Word a démarré en {0}.{1} secondes", ts.Seconds.ToString(),
ts.Milliseconds.ToString() );
Console.ReadLine();
Surveiller un processus
Les informations relatives au processus associé à l'objet Process sont disponibles dans ses propriétés. Ces informations ne sont pas constamment remises à jour. Elles sont renseignées uniquement lors de l'association du processus et de l'objet Process. Afin de provoquer une mise à jour de ces informations, il faut appeler la méthode Refresh, qui ne renvoie rien et ne prend aucun paramètre. Une fois cet appel réalisé, la prochaine fois que vous accèderez à une propriété de l'objet Process, celle-ci sera remise à jour.Voyons maintenant les propriétés de l'objet Process:
- int BasePriority: indique la priorité associée au processus. La valeur est basée sur celle de la propriété PriorityClass. BasePriority étant en lecture seule, vous devrez utiliser la propriété PriorityClass pour modifier la priorité du processus. L'accès à cette propriété peut provoquer une InvalidOperationException si le processus est terminé ou qu'il n'est pas encore démarré. Les valeurs ont la signification suivante: 4 correspond à la priorité Idle, 8 à Normal, 13 à High et 24 à RealTime. Le système peut décider, selon certains critères, de changer la priorité d'un processus.Attention, cette propriété n'est pas disponible sous Windows 98 si le processus a été démarrré avec UseShellExecute à true.
- bool EnableRaisingEvents: indique si l'évènement Exited arrive lorsque le processus se termine. La valeur par défaut est false.
- int ExitCode: le code qu'a renvoyé le processus lorsqu'il s'est terminé. L'accès à cette propriété provoquera une InvalidOperationException si le processus n'est pas terminé ou bien que la propriété Handle n'est pas valide.
- DateTime ExitTime: indique l'heure à laquelle s'est terminé le processus. Son accès peut provoquer une PlatfomNotSupportedException si vous êtes sous Windows 98.
- IntPtr Handle: contient le handle du processus associé. Ce handle est unique au sein de l'application, et ne peut être partagé. Un processus possède également un Id, qui, lui, est valide dans tout le système et peut donc être partagé. Seuls les processus démarrés grâce à la méthode Start mettent à jour la valeur de Handle. Une InvalidOperationException peut être levée si vous tentez d'accéder à cette propriété alors qu'aucun processus n'est associé à l'objet Process ou que l'objet n'a pas les permissions nécessaires pour récupérer le handle du processus qui lui est associé.
- int HandleCount: contient le nombre de handles ouverts par le processus. (handles sur des fichiers, ressources etc...) Le système ne reprend la mémoire allouée au processus que lorsque ce nombre atteint 0. Cette propriété est inaccessible sous Windows 98 si le processus a été démarré avec UseShellExecute à true.
- bool HasExited: indique si le processus est terminé ou non. Son accès peut causer une InvalidOperationException si aucun processus n'est associé à l'objet, et une Win32Exception si le code de sortie (ExitCode) n'a pas pu être récupéré.
- int Id: contient l'identifiant unique et généré par le système qui identifie le processus associé. Cet identifiant est valable sur tout le système. Il permet par exemple d'associer un objet Process à un processus local ou distant, grâce à la méthode GetProcessById. Bien sûr, cet identifiant n'est valable que pendant le temps de vie du processus. Son accès provoque une InvalidOperationException si l'Id n'a pas été renseigné ou s'il n'y a pas de processus associé. Cette propriété est inaccessible sous Windows 98 si le processus a été démarré avec UseShellExecute à true.
- string MachineName: contient le nom de la machine sur laquelle tourne le processus
- ProcessModule MainModule: contient le principal module associé au processus. Cette propriété est inaccessible sous Windows 98 si le processus a été démarré avec UseShellExecute à true. Elle n'est pas non plus accessible sur un processus distant. Dans ce cas, tenter d'y accéder lèvera une NotSupportedException.
- IntPtr MainWindowHandle: contient un handle sur la fenêtre principale de l'application qui s'exécute dans le processus. Y accéder lèvera une InvalidOperationException si le processus est terminé, et une NotSupportedException s'il s'agit d'un processus distant.
- string MainWindowTitle: contient le titre de la fenêtre principale. Si le processus vient juste d'être lancé, il est plus prudent d'utiliser la méthode WaitForInputIdle afin d'être certains que le processus a bien fini de démarrer avant de modifier cette propriété. Si ce n'est pas le cas, un exception sera levée. Cette propriété est inaccessible sous Windows 98 si le processus a été démarré avec UseShellExecute à true.
- IntPtr MaxWorkingSet: indique et permet de spécifier la taille maximale de la mémoire de travail allouée au processus. Son accès provoquera une PlatformNotSupportedException sous Windows 98. Une Win32Exception pourra être levée si l'information ne peut être obtenue à partir du processus ou s'il n'est pas démarré. Pour finir, une NotSupportedException sera levée si le processus est distant, et une InvalidOperationException le sera si l'Id du processus n'est pas disponible.
- IntPtr MinWorkingSet: indique et permet de spécifier la taille minimale de la mémoire de travail allouée au processus. Son accès provoquera une PlatformNotSupportedException sous Windows 98. Une Win32Exception pourra être levée si l'information ne peut être obtenue à partir du processus ou s'il n'est pas démarré. Pour finir, une NotSupportedException sera levée si le processus est distant, et une InvalidOperationException le sera si l'Id du processus n'est pas disponible.
- ProcessModuleCollection Modules: contient un objet ProcessModuleCollection avec les modules chargés dans le processus. Y accéder provoque une SystemException si l'Id du processus n'est pas disponible ou si le processus est distant.
- int PagedMemorySize: indique le montant de mémoire pouvant pas être écrite en mémoire virtuelle alloué par le processus. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- int NonpagedSystemMemorySize: indique le montant de mémoire ne pouvant pas être écrite en mémoire virtuelle alloué au le processus par le système. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- int PagedSystemMemorySize: indique le montant de mémoire pouvant pas être écrite en mémoire virtuelle alloué au processus par le système. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- int PeakPagedMemorySize: indique le montant maximum de mémoire pouvant pas être écrite en mémoire virtuelle alloué au processus par le système. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- int PeakVirtualMemorySize: indique le montant maximum de mémoire virutelle que le processus a demandé. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- int PeakWorkingSet: indique le montant maximum de mémoire que le processus a consommé. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- bool PriorityBoostEnabled: indique si la priorité du processus peut être temporairement augmentée par le système d'exploitation lorsque l'application est au premier plan. Une Win32Exception peut être levée si la propriété ne peut être lue à partir du processus. Si vous essayez d'accéder à cette propriété à partir de Windows 98, ou que le handle du processus est à zéro, (ie le processus n'a pas démarré) une PlatformNotSupportedException sera levée. Une SystemException sera levée si le processus est un processus distant ou si l'Id du processus n'est pas disponible.
- ProcessPriorityClass PriorityClass: définit le priorité du processus. ProcessPriorityClass est une énumération qui peut prendre les valeurs Idle, BelowNormal, Normal, AboveNormal, High ou RealTime. Les valeurs AboveNormal et BelowNormal ne sont pas disponibles sous Windows 98. Les spécifier aura pour conséquence la levée d'une PlatformNotSupportedException. Une Win32Exception sera levée si l'information est inaccessible ou que le processus n'est pas démarré. Si le processus est distant ou que la propriété Id est inaccessible, c'est une SystemException qui sera levée.
- int PrivateMemorySize: indique le montant de mémoire non partageable allouée par le processus. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- TimeSpan PrivilegedProcessorTime: indique le temps passé par le processus à exécuter du code dans le coeur de l'OS. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- string ProcessName: contient le nom du processus. Son accès provoque une SystemException si le processus est terminé, ou s'il n'y a pas de processus associée à l'objet Process. Cette propriété est inaccessible sous Windows 98 si le processus a été démarré avec UseShellExecute à true.
- IntPtr ProcessorAffinity: contient un masque de bits qui représente les processeurs sur lesquels peuvent tourner les threads associées aux processus. La valeur par défaut dépend du nombre de CPU présents sur la machine. Elle est de 2n-1, où n est le nombre de processeurs. Sous Windows 2000 et supérieur, un thread d'un processus peut changer de processeur. Chaque changement implique un rechargement du cache du processeur. Si le système supporte une lourde charge, spécifier quel processeur doit prendre en charge quel thread peut améliorer les performances, puisque cela réduit le nombre de rechargements de la cache. C'est cette association entre un processeur et un thread qui est appelée "processor affinity". Chaque bit mis à 1 dans le masque représente un processeur auquel est assigné le thread. Si tout les bits sont à zéro, c'est l'OS qui s'occupera de la répartition. L'accès ou la modification de cette propriété peut lever une Win32Exception si les informations sont inaccessibles ou que le processus n'est pas démarré. Une SystemException sera levée si l'Id du processus n'est pas disponible, ou si le processus est terminé.
- bool Responding: indique si l'interface graphique du processus renvoie une réponse. Si le processus a une interface utilisateur, cette propriété la contacte pour tester si elle répond aux entrées utilisateur. Si le processus n'a pas d'interface, cette propriété renvoie toujours true. C'est cette propriété qui est utilisée par le gestionnaire de tâches lorsqu'il affiche "pas de réponse" en face du nom d'un processus. Cette propriété est inaccessible sous Windows 98 si le processus a été démarré avec UseShellExecute à true.
- StreamReader StandardError: contient un StreamReader qui lit la sortie de l'application consacrée aux erreurs via un flux de fichier sur un des threads de l'application. C'est votre application qui définit comment lui sont envoyées les informations.
- StreamWriter StandardInput: contient un StreamWriter qui va transmettre les entrées utilisateur au processus via un flux de fichier.
- StreamReader Standard Output: contient un StreamReader qui lit la sortie de l'application via un flux de fichier. Cette propriété peut être utilisée avec un processus que vous avez créé vous-même, mais avec un processus existant.
- ProcessStartInfo StartInfo: contient des informations à passer à la méthode Start lors du démarrage du processus. Voir "démarrer un processus" pour plus d'infomations.
- DateTime StartTime: indique l'heure à laquelle le processus associé a démarré. Son accès provoquera une PlatformNotSupportedException sous Windows 98.
- ProcessThreadsCollection Threads: donne une collection de threads représentant les threads tournant dans ce processus. Une SystemException sera levée si le processus est terminé, qu'il n'a pas d'Id, ou qu'il est inexistant.
- TimeSpan TotalProcessorTime: indique le temps que le processus a pu utiliser le CPU. Cette valeur est la somme de UserProcessorTime et PrivilegedProcessorTime. L'accès à cette propriété provoquera une PlatformNotSupportedException sous Windows 98.
- TimeSpan UserProcessorTime: indique le temps que le processus a passé à exécuter du code dans la partie applicative du processus. (c'est à dire en dehors du coeur de l'OS) L'accès à cette propriété provoquera une PlatformNotSupportedException sous Windows 98.
- int VirtualMemorySize: indique le montant de mémoire virtuelle que le processus demande. L'accès à cette propriété provoquera une PlatformNotSupportedException sous Windows 98.
- int WorkingSet: indique le montant total de mémoire utilisée par le processus. L'accès à cette propriété provoquera une PlatformNotSupportedException sous Windows 98.
Annexe
Pour illustrer ce cours, nous avons développé l'application ProcessViewer, qui est une version allégée du gestionnaire de tâches. Vous pouvez la télécharger, ainsi que son code source, en cliquant ici (http://www.mangue.org/cours/csharp/download/ProcessViewer.zip).
Vous trouverez également ici (http://www.mangue.org/cours/csharp/download/waitforinputidle.zip) une illustration de la méthode WaitForInputIdle.

