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#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    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 Expert
    Avatar de PixelJuice
    Homme Profil pro
    Ingénieur .NET & Game Designer
    Inscrit en
    Janvier 2014
    Messages
    667
    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 : 667
    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 Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 204
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 204
    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 confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    88
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    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 confirmé

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

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

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    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).

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

    Informations forums :
    Inscription : Mai 2006
    Messages : 88
    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...

+ 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