181 votes

Comment puis-je savoir si un processus est en cours d'exécution?

Lorsque j'obtiens une référence à un System.Diagnostics.Process, comment puis-je savoir si un processus est actuellement en cours d'exécution ?

288voto

Patrick Desjardins Points 51478

C'est une manière de le faire avec le nom :

Process[] pname = Process.GetProcessesByName("notepad");
if (pname.Length == 0)
  MessageBox.Show("rien");
else
  MessageBox.Show("exécuter");

Vous pouvez parcourir tous les processus pour obtenir l'ID pour une manipulation ultérieure :

Process[] processlist = Process.GetProcesses();
foreach(Process theprocess in processlist){
   Console.WriteLine("Processus : {0} ID : {1}", theprocess.ProcessName, theprocess.Id);
}

0 votes

C'est exactement ce que je cherchais. Même si c'est un post très ancien, pourriez-vous m'expliquer comment ceci est du C# valide. Je ne doute pas que cela fonctionne, mais je n'ai jamais vu de if else sans { }.

7 votes

@MatthewD: Les instructions en une ligne de C# if / else n'ont pas besoin d'avoir des accolades pour indiquer le bloc de code. Cela s'applique également aux instructions foreach et for. Cela revient au style de codage.

1 votes

J'ai également fait des recherches sur cela, trouvé cette info, mais je n'ai pas vu l' for info. Des années de développement en c# .net et je n'ai jamais vu ce style. Comme on dit, "on apprend quelque chose de nouveau chaque jour". Merci pour le post et la réponse.

34voto

reshefm Points 1719

C'est la façon la plus simple que j'ai trouvée après avoir utilisé le réflecteur. J'ai créé une méthode d'extension pour cela :

public static class ProcessExtensions
{
    public static bool IsRunning(this Process process)
    {
        if (process == null) 
            throw new ArgumentNullException("process");

        try
        {
            Process.GetProcessById(process.Id);
        }
        catch (ArgumentException)
        {
            return false;
        }
        return true;
    }
}

La méthode Process.GetProcessById(processId) appelle la méthode ProcessManager.IsProcessRunning(processId) et lance une ArgumentException en cas de processus inexistant. Pour une raison quelconque, la classe ProcessManager est interne...

0 votes

C'était vraiment une bonne réponse; cependant, vous n'auriez pas dû provoquer l'exception d'argument null (car de toute façon une exception de référence nulle aurait été levée et vous n'avez rien fait avec l'exception. De plus, vous obtiendrez une InvalidOperationException si vous n'avez pas invoqué la méthode Start() ou si vous avez invoqué la méthode close(). J'ai posté une autre réponse pour tenir compte de ces deux situations.

0 votes

Et si un autre processus prenait l'identifiant du processus initial qui n'est plus en cours d'exécution ? Est-ce possible ?

19voto

Coincoin Points 12823

Solution synchrone :

void AfficherEtatProcessus(Process processus)
{
    processus.Refresh();  // Important

    if(processus.HasExited)
    {
        Console.WriteLine("Arrêté.");
    }
    else
    {
        Console.WriteLine("En cours d'exécution.");
    } 
}

Solution asynchrone:

void EnregistrerSortieProcessus(Process processus)
{
    // REMARQUE : il y aura une condition de concurrence avec l'appelant ici
    //   comment la corriger est laissée en exercice
    processus.Exited += processus_Exité;
}

static void processus_Exité(object sender, EventArgs e)
{
   Console.WriteLine("Le processus s'est arrêté.");
}

7 votes

Pour la première option : comment puis-je savoir si le processus a été démarré en premier lieu?

11voto

Aelphaeis Points 949

Reshefm avait une réponse plutôt bonne; cependant, elle ne tient pas compte d'une situation dans laquelle le processus n'a jamais été démarré pour commencer.

Voici une version modifiée de ce qu'il a posté.

public static bool IsRunning(this Process process)
{
    try
    {
        Process.GetProcessById(process.Id).Dispose();
    }
    catch (Exception e) when (e is ArgumentException or InvalidOperationException)
    {
        return false;
    }
    return true;
}

J'ai supprimé son ArgumentNullException car elle est censée être une exception de référence nulle et elle est lancée par le système de toute façon, et j'ai aussi pris en compte la situation dans laquelle le processus n'a jamais été démarré à l'origine ou la méthode close() a été utilisée pour fermer le processus.

0 votes

Personnellement, je préférerais voir une ArgumentNullException lors de l'examen d'une exception enregistrée plutôt qu'une NullReferenceException, car ArgumentNullException est beaucoup plus explicite sur ce qui s'est mal passé.

1 votes

@Sean Je serais normalement d'accord avec toi, mais il s'agit d'une méthode d'extension. Je pense qu'il est plus approprié de déclencher une exception de pointeur null compte tenu de la syntaxe, cela semble simplement plus cohérent avec l'appel de méthodes d'objets nuls.

0 votes

Cela déclenchera le gestionnaire d'événements FirstHandledException à chaque fois. Belle manière de spammer vos journaux, mon ami.

1voto

Jeff Kotula Points 1737

Process.GetProcesses() est la solution à privilégier. Mais vous pourriez avoir besoin d'utiliser un ou plusieurs critères différents pour trouver votre processus, en fonction de la manière dont il est en cours d'exécution (c'est-à-dire en tant que service ou une application normale, qu'il ait ou non une barre de titre).

1 votes

Si vous mettez cette méthode dans une boucle, cela coûte beaucoup de cycles CPU. Je recommande d'utiliser GetProcessByName() ou GetProcessByID().

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X