2012-05-22 11 views
5

Así que tengo un dll C++, que estoy usando en mi aplicación C#, para monitorear los mensajes de Windows. Quiero saber si se envían WM_CLOSE y WM_QUERYENDSESSION porque no puedo ver eso desde una aplicación C#. Si recibo uno de estos mensajes, quiero hacer algo de limpieza con mis archivos pero el problema es que cuando lo mato con TM, las funciones no funcionan. Parece que no recibo los mensajes. Creo que el problema es que el Administrador de tareas envía un mensaje a la aplicación C# y no al C++ dll.Qué mensaje recibo cuando elimino mi programa con el administrador de tareas

Algunos Código:

C++:

typedef void (*CLOSING_FUNCTION)(); 
CLOSING_FUNCTION myClosingFunction; 

typedef void (*SHUTDOWN_FUNCTION)(); 
SHUTDOWN_FUNCTION myShutdownFunction; 

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
    switch(message) 
    { 

    case WM_CREATE: 
     return 0; 

    case WM_CLOSE: 
     myClosingFunction(); 
     return 0; 

    case WM_QUERYENDSESSION: 
     myShutdownFunction(); 
     return 1; 

    case WM_DESTROY: 
     myClosingFunction(); 
     PostQuitMessage(0); 
     return 0; 
    } 

    return DefWindowProc(hwnd, message, wParam, lParam); 
} 

C#:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
private delegate void Close_Function(); 
private static Close_Function myCloseDelegate; 

[UnmanagedFunctionPointer(CallingConvention.Cdecl)] 
private delegate void Shutdown_Function(); 
private static Shutdown_Function myShutdownDelegate; 
static void StartMonotoring() 
{ 
     myCloseDelegate = Close; 
     myShutdownDelegate = Shutdown; 

     InterceptMessages(myCloseDelegate, myShutdownDelegate); 
} 

static void Close(); 
static void Shutdown(); 
+2

Solo obtiene WM_CLOSE cuando usa la pestaña Aplicaciones en el administrador de tareas. Eliminarlo de la pestaña Procesos es una terminación grosera. No está claro cómo termina el mensaje en el código C++, la IU generalmente se realiza en C#. –

+2

O obtendrá un evento 'CTRL_CLOSE_EVENT' en las aplicaciones de la consola. Obligatorio enlace a la vieja noticia relevante [blog] (http://blogs.msdn.com/b/oldnewthing/archive/2004/07/22/191123.aspx) –

Respuesta

3

Su proceso no recibirá mensajes en caso de que si está siendo asesinada. Comience en TerminateProcess - vea lo más destacado:

La función TerminateProcess se utiliza para que un proceso salga incondicionalmente. El estado de los datos globales mantenidos por las bibliotecas de vínculos dinámicos (DLL) puede verse comprometido si se utiliza TerminateProcess en lugar de ExitProcess.

Esta función detiene la ejecución de todas las discusiones dentro del proceso y solicita la cancelación de toda ... O

edición pendiente de E /: comentario Hans Passant en las tareas manera terminado - usted consigue solamente cuando se utiliza WM_CLOSE la pestaña Aplicaciones en el administrador de tareas. Eliminarlo de la pestaña Procesos es una terminación grosera (TerminateProcess).

+0

Y en caso de un apagado iniciado WM_QUERYENDSESSION? – Thanatos

+1

sí. Nota al margen sobre el administrador de tareas: creo que hay (¿hay?) Casos en que el administrador de tareas intenta detener el proceso correctamente antes de finalizar, pero yo solo esperaría que TerminateProcess se utilizara en el proceso si es importante para usted. –

+0

Entonces, ¿conoce una forma de averiguar si el apagado se inició con C#? en winapi usé el queryendsesion pero aquí? – Thanatos

Cuestiones relacionadas