0

I am using the following code to handle taskkill on my process:

[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
private class TestMessageFilter : IMessageFilter
{
    public bool PreFilterMessage(ref Message m)
    {
        if (m.Msg == /*WM_CLOSE*/ 0x10)
        {
            MessageBox.Show("I'm shutting down");
            var mailService = new MailService();
            mailService.SendEmail("Test from application exit");
            //Application.Exit();
            return true;
        }
        return false;
    }
}

and then

static void Main(string[] args)
{
    Application.AddMessageFilter(new TestMessageFilter());
    Application.Run();
}

The MessageBox pops up and the email is sent when I do taskkill /im MyProcess.exe. However this does not happen on windows shutdown.

Does Windows kill processes forcefully on shutdown or is it me who's missing something?

iuliu.net
  • 6,666
  • 6
  • 46
  • 69

2 Answers2

1

That you can see WM_CLOSE at all in an IMessageFilter is quite accidental and an implementation detail of taskkill.exe. You normally only see posted messages, WM_CLOSE is normally sent. I think you see taskkill.exe first trying to ask nicely, only using the sledge-hammer when the app doesn't respond fast enough. Task Manager used to do this as well but doesn't anymore in later Windows versions.

And no, it certainly can't work on a Windows shutdown. It sends a WM_QUERYENDSESSION message to a window to announce the shutdown.

Lots of good reasons to make this a service instead. But as long as you want to do it this way then you need a window to see that message. Subscribe its FormClosing event, the e.CloseReason property tells you why it is closing down. You'll see CloseReason.WindowsShutDown. You just need to keep the window invisible to keep it equivalent to what you have, override the SetVisibleCore() method as shown in this post.

Community
  • 1
  • 1
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
0

The general pattern operating systems use is to request that running processes terminate gracefully, then kill them if they don't terminate within a timeout. Some applications will pop up a save changes prompt on shutdown, but they may not actually appear to the user - Windows can display a "shutting down" screen and say that some processes are still running - do you want to kill them and shut down anyway?

I believe if you're using Windows Forms you can achieve the same result as you have here with the Closing/Closed events*, so you could see if either of those fire by saving some text to a file (and make sure to flush it), and also see if you get any other message codes in PreFilterMessage in the same way.

*You could get either Closing or Closed or both, so check both. e.g. you can get a Closed without a prior Closing.

George Helyar
  • 4,319
  • 1
  • 22
  • 20