2012-05-22 8 views
5

Итак, у меня есть dll C++, который я использую в своем приложении C# для мониторинга сообщений Windows. Я хочу знать, отправляются ли WM_CLOSE и WM_QUERYENDSESSION, потому что я не вижу этого из приложения C#. Если я получаю одно из этих сообщений, я хочу сделать некоторую очистку с моими файлами, но проблема в том, что я убиваю его с помощью TM, функции не работают. Это швы, что я не получаю сообщения. Я думаю, проблема заключается в том, что диспетчер задач отправляет сообщение в приложение C#, а не в dll C++.Какое сообщение я получаю, когда убью свою программу с помощью диспетчера задач

Некоторые Код:

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

При использовании вкладки «Приложения» в диспетчере задач вы получаете WM_CLOSE. Убить его с вкладки «Процессы» является грубое завершение. Как сообщение в коде C++ очень неясно, пользовательский интерфейс обычно выполняется на C#. –

+2

Или вы получите событие CTRL_CLOSE_EVENT в консольных приложениях. Обязательная ссылка на соответствующее oldnewthing [сообщение в блоге] (http://blogs.msdn.com/b/oldnewthing/archive/2004/07/22/191123.aspx) –

ответ

3

Ваш процесс не получит никаких сообщений в случае, если он был убит. Начать с TerminateProcess - см. Мою подсветку:

Функция TerminateProcess используется для безоговорочного завершения процесса. Состояние глобальных данных, поддерживаемых библиотеками динамической компоновки (DLL), может быть скомпрометировано, если TerminateProcess используется, а не ExitProcess.

Эта функция останавливает выполнение всех потоков в процессе и просит отмены всех в ожидании ввода-вывода ...

EDIT /: Hans Passant комментарий на пути задач прекращается - Вы можете получить только при использовании WM_CLOSE вкладку «Приложения» в диспетчере задач. Убить его с вкладки «Процессы» является грубое завершение (TerminateProcess).

+0

И в случае инициированного отключения WM_QUERYENDSESSION? – Thanatos

+1

есть. Замечание в диспетчере задач: я думаю, что есть (были?) Случаи, когда диспетчер задач пытается нормально остановить процесс до завершения, но я бы просто ожидал, что TerminateProcess будет использоваться в процессе, если это важно для вас. –

+0

Знаете ли вы, как узнать, была ли остановка запущена с использованием C#? в winapi я использовал запрос, но здесь? – Thanatos