2009-10-26 17 views
13

Mi programa coloca un icono en la bandeja del sistema porque el usuario puede minimizarlo. Sin embargo, si la aplicación falla, o detengo la aplicación para que no se ejecute en VS, deja el icono en ella hasta que sobre ella pase el mouse. A veces miro hacia abajo y habrán 10 o más iconos.¿Cómo evitar dejar un icono en la bandeja del sistema al salir?

¿Puedo asegurarme de que el ícono desaparezca?

Respuesta

21

No hay manera para hacer esto. Windows no sondea su programa para ver si todavía está activo. Por lo tanto, su icono permanecerá en la bandeja del sistema hasta que le diga que se vaya (salida normal), o que el usuario haga algo que inicie una llamada a su programa (como mouseover). Solo entonces el shell sabe que su programa ha muerto y necesita limpiar su ícono.

+0

Así que no hay ningún evento que pueda tomar en caso de que el programa muera? – Malfist

+0

No, no hay evento. Este es el comportamiento "normal" ... cada aplicación que tiene un icono de bandeja de sistema deja su ícono atrás cuando sale anormalmente. – jrista

+1

Es muy poco probable que no tenga la oportunidad de limpiar su icono. AppDomain.ProcessExit es un evento bastante bueno para escuchar para la salida del proceso. A menos que llame a Environment.FailFast() probablemente se llamará incluso en circunstancias "catastróficas" –

3

Antes de salir, establezca la propiedad NotifyIcon Visible en false.

+1

Pero se aclara que cuando el programa sale correctamente. Pero si el programa muere, se mata o se cuelga, sale del ícono. – Malfist

+2

A juzgar por la cantidad de productos que tienen este mismo comportamiento, es un problema difícil de resolver. –

+0

aunque no es la mejor solución, ¡pero es un buen truco para resolverlo rápido! – Arash

3

Debe llamar a Dispose en NotifyIcon para que salga de la bandeja.

EDITAR: Hay un evento que puede enganchar en su Program.cs. Para todas las aplicaciones de Windows, tendrá algo como esto:

[STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 

la clase de aplicación tiene una serie de eventos que puede tomar ventaja de saber cuando su aplicación muere:

 Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException); 
     Application.ApplicationExit += new EventHandler(Application_ApplicationExit); 
+0

¿Pero dónde/cuándo? – Malfist

+1

El OP menciona que ve el problema solo cuando su aplicación muere, o la mata. En esas situaciones, no se invocará Dispose(). –

4

tiene varias opciones:

1) un gestor de excepciones raíz estructurado que garantiza la destrucción del icono antes de la salida. Esto requiere un poco de esfuerzo, pero básicamente puedes agregar tu propio manejador de excepciones no manejadas a Windows, que se llamará en el caso de muchas formas de "auge", que te permitirán una última oportunidad de limpieza.

2) Escriba una aplicación de monitor que duerma en el control de procesos principal y elimine el icono cuando se active (la aplicación principal ha muerto). Para que este último escenario funcione bien, es probable que desee que el proceso principal NO mate el icono en sí, o podría crear una forma de decirle a la aplicación del monitor que debe salir sin destruir el ícono (haga que la aplicación del monitor duerma tanto en el identificador del proceso como en un evento con nombre, y si el evento lo despierta, simplemente muere sin limpieza después de la aplicación principal).

+0

D'oh - Debería haber notado el idioma. La opción n. ° 1 está disponible para C o C++, pero no estoy seguro de que esté disponible para una aplicación de C#, por lo que es posible que se vea obligado a hacer el n. ° 2. – Mordachai

+0

# 2 es la opción más robusta, de todos modos. # 1 no sería bueno si el proceso se matara en el Administrador de tareas, o como se menciona el PO, si uno terminara abruptamente una sesión de depuración. –

-1

Podemos ocultar trayIcon antes de cerrar el formulario. Añadir FormClosing Evento

NotifyIcon ni; 
... 
... 
private void MainForm_FormClosing(object sender, FormClosingEventArgs e) 
{ 
    ni.Visible = false; 
} 
Cuestiones relacionadas