5

So I have a C++ dll, that I am using in my c# application, for monitoring Windows Messages. I want to know if WM_CLOSE and WM_QUERYENDSESSION are send because I can't see that from a C# application. If I get one of these messages, I want to do some cleanup with my files but the problem is when I kill it with TM the functions don't work. It seams that I don't get the messages. I think the problem is that Task Manager sends a message to the C# app and not to the c++ dll.

Some Code:

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();
Thanatos
  • 1,176
  • 8
  • 18
  • 2
    You only get WM_CLOSE when using the Applications tab in task manager. Killing it from the Processes tab is a rude termination. How message end up in the C++ code is very unclear, the UI is typically done in C#. – Hans Passant May 22 '12 at 17:01
  • 2
    Or you'll get a `CTRL_CLOSE_EVENT` event in console applications. Obligatory link to the relevant oldnewthing [blog post](http://blogs.msdn.com/b/oldnewthing/archive/2004/07/22/191123.aspx) – Christian.K May 22 '12 at 17:26

1 Answers1

4

Your process will not get any messages in case if it is being killed. Start on TerminateProcess - see my highlight:

The TerminateProcess function is used to unconditionally cause a process to exit. The state of global data maintained by dynamic-link libraries (DLLs) may be compromised if TerminateProcess is used rather than ExitProcess.

This function stops execution of all threads within the process and requests cancellation of all pending I/O...

EDIT: Hans Passant comment on way tasks terminated - You only get WM_CLOSE when using the Applications tab in task manager. Killing it from the Processes tab is a rude termination (TerminateProcess).

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • And in case of a initiated shutdown WM_QUERYENDSESSION? – Thanatos May 22 '12 at 16:53
  • 1
    yes. Side note on task manager: I think there are (were?) cases when task manager tries to properly stop process before terminating, but I'd just expect TerminateProcess to be used on process if it is important to you. – Alexei Levenkov May 22 '12 at 16:58
  • Then do you know a way to find out if shutdown was initiated using c#? in winapi i used the queryendsesion but here? – Thanatos May 22 '12 at 17:03
  • I don't. It is likely that there is no call in Framework to do so. PInvoke is always an option (check http://PInvoke.Net for the function you are looking for). – Alexei Levenkov May 22 '12 at 17:06