IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Tester si plusieurs programmes sont terminés avant de faire des actions [Débutant]


Sujet :

C#

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    Points : 48
    Points
    48
    Par défaut Tester si plusieurs programmes sont terminés avant de faire des actions
    Bonjour,

    Voici ce que je souhaite faire dans mon programme :

    Mon programme, lors d'un clic sur un bouton, lance x programmes (x est un nombre aléatoire) et désactive des boutons.

    Ensuite quand l'utilisateur à fermer (quitter) les x programmes lancés, mon programme reprend la main et réactive tous les boutons désactivés.

    Sauf à faire, dans la procédure/méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    private void OnBoutonClicker(object sender, EventArgs e)
    , une boucle infinie attendant que tous les processus liés aux x programmes soient terminés, boucle qui consomme beaucoup de ressources... je ne vois pas comment faire autrement.

    Avez-vous une idée ?

    Voici une partie de mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
     
            private void GenererBouton(string nomBouton, int PosX, int PosY, int Larg, int Haut, bool Visibilite, int DimXEcran, int DimYEcran)
            {
                // Instanciation du bouton
                Button bouton = new System.Windows.Forms.Button
                {
                    // Paramètres fixes du bouton
                    Size = new System.Drawing.Size(Larg, Haut),
                    Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(0))),
     
                    // Paramètres propres à chaque bouton
                    Name = nomBouton,
                    Text = nomBouton,
     
                    // Position sur l'écran
                    Top = PosY,
                    Left = PosX,
     
                    // Visibilité
                    Visible = Visibilite,
     
                    // Curseur souris
                    Cursor = Cursors.Hand
                };
     
                // Fonction du bouton sur son event Click
                bouton.Click += OnBoutonClicker;
     
                // Ajoute le bouton sur la fenêtre (VuePrincipale)
                listeBoutons.Add(bouton);
                this.Controls.Add(bouton); 
            }
     
            // Méthode appelée lorsqu'on clique sur un bouton
            private void OnBoutonClicker(object sender, EventArgs e)
            {
                // Récupération du bouton sollicité
                Button bouton = (Button)sender;
     
                // Initialise les boutons
                foreach (Button b in listeBoutons)
                {
                    b.BackColor = SystemColors.Control;
                    b.Enabled = false;
                }
     
                // Mofdification de la couleur du bouton
                bouton.BackColor = Color.SkyBlue;
     
                // Test si un processus Supervis est en cours d'exécution
                Process[] liste = Process.GetProcessesByName(K_nomProcess);
                foreach (Process p in liste)
                {
                    p.Kill(); //tuer tout les processus recupérés
                }
     
                // Lancer les applications correspondantes au bouton sollicité
                // On boucle s'il y a plusieurs programme à lancer
                // cheminAppli = répertoire contenant le nombre de fichiers bat à lancer chaque bat lance un programme .exe avec des paramètres
                string cheminAppli = @"C:\" + bouton.Name;
                DirectoryInfo Dossier = new DirectoryInfo(cheminAppli);
                FileInfo[] fichiers = Dossier.GetFiles("*.bat", SearchOption.TopDirectoryOnly);
                int nbFichiersBat = Dossier.GetFiles("*.bat", SearchOption.TopDirectoryOnly).Length - 1;
     
                if (nbFichiersBat < 0)
                {
                    message = "Le dossier \"" + cheminAppli + "\" ne contient aucun fichier à exécuter (*.bat).\n\r";
                    caption = "Erreur";
                    MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
     
                int i = 0;
                ProcessStartInfo[] prog = new ProcessStartInfo[fichiers.Length];
                Process[] monProcess = new Process[fichiers.Length];
                foreach (FileInfo file in fichiers)
                {
                    prog[i] = new ProcessStartInfo(cheminAppli + file.ToString())
                    {
                        CreateNoWindow = true,
                        UseShellExecute = false
                    };
     
                    // Déclaration d'un nouveau processus : permet de faire un monProcess.WaitForExit() si besoin et démarrage de l'application supervis.exe
                    monProcess[i] = Process.Start(prog[i]);
                    Thread.Sleep(500);
                    i += 1;
                }
     
                //i = 0;
                //liste = Process.GetProcessesByName(K_nomProcess);
                //monProcess = new Process[liste.Length];
                //foreach (Process p in liste)
                //{
                //    monProcess[i].WaitForExit();
                //    i += 1;
                //}
     
                // Vérification si des programmes en cours d'exécution
                bool flag = true;
                while (flag)
                {
                    // On reste dans la boucle tant que tous les programmes lancés ne sont pas fermés
                    flag = false;
                    liste = Process.GetProcessesByName(K_nomProcess);
                    foreach (Process p in liste)
                    {
                        flag = true;
                    }
                }
     
                // Si tous les programmes on été fermés : réinitialiser les boutons
                MessageBox.Show("L'application de supervision " + bouton.Name + " a été fermée.", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
     
                // Initialise les boutons
                foreach (Button b in listeBoutons)
                {
                    b.BackColor = SystemColors.Control;
                    b.Enabled = true;
                }
     
            }

  2. #2
    Membre chevronné
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    640
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Ingénieur .NET & Game Designer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2014
    Messages : 640
    Points : 2 149
    Points
    2 149
    Par défaut
    Bonjour,

    Il y a peut-être une façon + propre de gérer mais, si tu fais une boucle while, pense toujours à mettre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Thread.Sleep(100); // en millisecondes
    a la toute fin de ta boucle. Cela permet d'attendre quelques temps, afin que le programme n’exécute pas ton code autant que possible.

    Essaye déjà ça, les performances seront déjà bien meilleurs. Si jamais ce n'est pas suffisant, on pourra toujours trouver une meilleure solution.

  3. #3
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    c'est exactement ca, déjà avec thread.sleep(1) on voit la différence sur une boucle d'attente, mais ici 100 ms ou même un peu plus ca suffit (sans sleep tu vérifies plusieurs fois par milliseconde c'est inutile)


    au passage

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     while (flag)
                {
                    // On reste dans la boucle tant que tous les programmes lancés ne sont pas fermés
                    flag = false;
                    liste = Process.GetProcessesByName(K_nomProcess);
                    foreach (Process p in liste)
                    {
                        flag = true;
                    }
                }
    ca équivaut à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while (Process.GetProcessesByName(K_nomProcess).Count() > 0)
                {
                    thread.sleep(100);                
                }
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    Points : 48
    Points
    48
    Par défaut
    Merci pour vos propositions.

    J'avais déjà testé avec le Sleep mais ça ne me plait pas vraiment. Je pensais qu'il y avait une autre solution en utilisant pas exemple la propriété en combinaison avec d'autres commandes comme par exemple les abonnements (mais là c'est très flou pour moi).

    J'ai pour le moment contourné le problème en ne lançant qu'un ou deux programmes au lieu de x.

  5. #5
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    La méthode la plus propre est de passer par l'événement Process.Exited.

    En gros, tu auras une méthode qui sera appelée automatiquement lorsque le processus fils se terminera (que ce soit avec ou sans erreur).
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par François DORIN Voir le message
    La méthode la plus propre est de passer par l'événement Process.Exited.

    En gros, tu auras une méthode qui sera appelée automatiquement lorsque le processus fils se terminera (que ce soit avec ou sans erreur).
    Oui, mais là ou je bloque c'est sur le nombre aléatoire x d'application qui peut-être ouverte (pour le moment limité à 2) : je vois pas trop comment utiliser sans faire des if ou une boucle infinie...

  7. #7
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Tu évites les boucles (pas les if). Dès qu'un programme ferme, tu vérifies s'il existe encore des programmes qui tourne. Si oui, tu ne fais rien. Si non, tu lances ton action.
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    Points : 48
    Points
    48
    Par défaut
    Citation Envoyé par François DORIN Voir le message
    Tu évites les boucles (pas les if). Dès qu'un programme ferme, tu vérifies s'il existe encore des programmes qui tourne. Si oui, tu ne fais rien. Si non, tu lances ton action.
    OK, mais comment dans le code avoir un nombre aléatoire de if ??? car x programmes (x aléatoires) = x if, non ?

  9. #9
    Expert éminent sénior

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 757
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 757
    Points : 10 541
    Points
    10 541
    Billets dans le blog
    21
    Par défaut
    Pas besoin d'avoir plusieurs conditionnelles. Une seule suffit pour déterminer s'il y a des programmes qui tournent encore ou pas. Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    void CheckRunningProcess(Process[] processes)
    {
       bool isRunning = false;
       foreach(Process process in processes)
       {
          if (!process.HasExited)
          {
             isRunning = true;
          }
       }
     
       if (!isRunning)
       {
         // Ton code à exécuter quand les programmes sont terminés.
       }
    }
    Et quand tu crées un processus, tu enregistres un délégué avant de le lancer :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    monProcess[i] = new Process();
    monProcess[i].Exited += (sender, object) => {CheckRunningProcess(monPrcess);};
    monProcess[i].Start();
    François DORIN
    Consultant informatique : conception, modélisation, développement (C#/.Net et SQL Server)
    Site internet | Profils Viadéo & LinkedIn
    ---------
    Page de cours : fdorin.developpez.com
    ---------
    N'oubliez pas de consulter la FAQ C# ainsi que les cours et tutoriels

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    Points : 48
    Points
    48
    Par défaut
    Ah...Ok je vais essayer.

    Merci.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    Points : 48
    Points
    48
    Par défaut
    C'est bon, grâce à vous je m'en suis sorti.

    Merci à tous !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 25/10/2016, 19h11
  2. Tester Plusieurs fichiers si fermé avant traitement
    Par mouss4rs dans le forum Entrée/Sortie
    Réponses: 11
    Dernier message: 09/05/2012, 16h19
  3. Programmes qui se terminent avant même d'être initialisés
    Par rock_and_lol dans le forum Débuter
    Réponses: 2
    Dernier message: 06/05/2011, 10h23
  4. Réponses: 5
    Dernier message: 02/08/2008, 23h23
  5. Réponses: 3
    Dernier message: 29/08/2007, 14h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo