87 votes

NotifyIcon reste dans le Tray même après la fermeture de l'application mais disparaît au passage de la souris

Il y a beaucoup de questions sur SO qui posent le même doute. La solution à ce problème est de définir

notifyIcon.icon = null et en appelant Dispose dans l'événement FormClosing.

Dans mon application, il n'y a pas de formulaire de ce type mais une icône de notification qui est mise à jour sur les événements. Lors de la création, je cache mon formulaire et je fais ShowInTaskbar propriété false . Je ne peux donc pas avoir d'événements "FormClosing" ou "FormClosed".

Si cette application reçoit un événement pour sortir, elle appelle Process.GetCurrentProcess().Kill(); pour sortir.

J'ai ajouté notifyIcon.icon = null ainsi que Dispose before killing, mais l'icône reste dans la barre des tâches jusqu'à ce que je passe la souris dessus.

EDIT : Si je suppose que ce comportement est dû au fait d'appeler GetCurrentProcess().Kill() Est-ce qu'il existe un moyen élégant de quitter l'application en vidant toutes les ressources et en supprimant l'icône de la barre d'état système ?

1voto

Terrence Meehan Points 21

Je les ai toutes essayées et aucune n'a fonctionné pour moi. Après avoir réfléchi un moment, j'ai réalisé que l'application qui créait le "ballon" se terminait avant d'avoir eu la possibilité de se débarrasser du ballon. J'ai ajouté une boucle while juste avant Application.Exit() contenant un Application.DoEvents() commandement. Cela a permis à mon NotifyIcon1_BalloonTipClosed pour finir de se débarrasser de l'icône avant de quitter.

while (notifyIcon1.Visible)
{
    Application.DoEvents();
}
Application.Exit();

Et la méthode de fermeture de l'astuce : (Vous devez inclure l'élément thisIcon.visible = false pour que cela fonctionne)

private void NotifyIcon1_BalloonTipClosed(object sender, EventArgs e)
{
    var thisIcon = (NotifyIcon)sender;
    thisIcon.Icon = null;
    thisIcon.Visible = false;
    thisIcon.Dispose();
}

0voto

victor Points 103

J'ai eu exactement le même problème que vous.

La bonne façon d'envoyer le message WM_CLOSE à un processus.
J'utilise le code c# que j'ai trouvé dans cet article.
http://social.msdn.microsoft.com/Forums/vstudio/en-US/82992842-80eb-43c8-a9e6-0a6a1d19b00f/terminating-a-process-in-a-friendly-way

0voto

Can DOGRU Points 49

Modifier les codes de ...Designer.cs comme le codage ci-dessous.

        protected override void Dispose(bool disposing)
           {
           if (disposing )
               {
               this.notifyicon.Dispose();
               }
           base.Dispose(disposing);
           }

0voto

BitWiseByteDumb Points 35

Je n'ai pu faire fonctionner aucune des autres solutions. Il s'est avéré être une sorte d'hybride de tout ce qui précède ! J'ai chassé et picoré jusqu'à ce que j'obtienne une solution qui fonctionne de manière cohérente, à la fois en mode débogage et en mode exécution EXE ! Je n'ai aucune idée de la raison pour laquelle MSFT a marqué ce problème comme étant "non réparable" ? J'aimerais avoir cette liberté !

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        //THIS CODE IS CRAZY BUT MUST BE DONE IN ORDER TO PROPERLY REMOVE THE SYSTEM TRAY ICON!
        //GREAT ARTICLE ON THIS ON STACK OVERFLOW
        //https://stackoverflow.com/questions/14723843/notifyicon-remains-in-tray-even-after-application-closing-but-disappears-on-mous

        //BTW THIS IS KIND OF A BLEND OF ALL THE SOLUTIONS BECAUSE I COULD NOT FIND A SINGLE SOLUTION THAT WOULD WORK!
        systray_icon.Visible = false;
        while (systray_icon.Visible)
        {
            Application.DoEvents();
        }
        systray_icon.Icon.Dispose();
        systray_icon.Dispose();
        Environment.Exit(1);
    }

-2voto

La bonne réponse a déjà été donnée. Mais vous devez également prévoir un délai, par exemple avec une minuterie. Ce n'est qu'alors que l'application peut encore supprimer l'icône en arrière-plan.

private System.Windows.Forms.Timer mCloseAppTimer;
private void ExitButton_Click(object sender, EventArgs e) 
{ 
    notifyIcon.Visible = false; notifyIcon.Dispose; 
    mCloseAppTimer = new System.Windows.Forms.Timer(); 
    mCloseAppTimer.Interval = 100; 
    mCloseAppTimer.Tick += new EventHandler(OnCloseAppTimerTick); 
} 
private void OnCloseAppTimerTick(object sender, EventArgs e) 
{ 
    Environment.Exit(0); // other exit codes are also possible 
}

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