locked
Delay Windows Shutdown/Restart RRS feed

  • Question

  • Gurus,

    I am trying to delay Windows Shutdown/Restart to perfrom cleanup and I am using the following code:

     

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]

    protected override void WndProc(ref Message ex)

    {

    if (ex.Msg == WM_QUERYENDSESSION)

    {

    //cancel the Shutdown/Restart

    Message MyMsg = new Message();

    MyMsg.Msg = WM_CANCELMODE;

    base.WndProc(ref MyMsg);

     

    //do the necessary work

     

    //Run the Issued Restart/Shutdown command

    base.WndProc(ref ex);

    }

    else

    {

    //send the message as normal

    base.WndProc(ref ex);

    }

    }

     

    But I realize that the cancel message is not being passed to other windows if I do this and other applications start displaying error/crash messages because they begin to shutdown. It looks like 'base.WndProc' sends message a message only after you come out of the WndProc method and hence you cannot pass both WM_CANCELMODE and Message ex within the same method call.

     

    The Message 'ex' cannot be unfortunately used to distinguish between Restart/Shutdown and I need to perform whatever was requested after performing the required operations.

     

    Please let me know if there are any alternatives.

    Any help is greatly appreciated. Thanks in advance.

    Friday, May 16, 2008 8:34 PM

Answers

  • The Win32 function BroadcastSystemMessage might be what you are looking for. You'll have to prototype it into your C# app first though.  Something like this:

     

    Code Snippet

    #region BroadcastSystemMessage

     

    enum WinMessages

    {

    WM_CANCELMODE = 0x001F,

    }

     

    [Flags]

    enum BSF

    {

    BSF_QUERY = 0x00000001,

    BSF_IGNORECURRENTTASK = 0x00000002,

    BSF_FLUSHDISK = 0x00000004,

    BSF_NOHANG = 0x00000008,

    BSF_POSTMESSAGE = 0x00000010,

    BSF_FORCEIFHUNG = 0x00000020,

    BSF_NOTIMEOUTIFNOTHUNG = 0x00000040,

    BSF_ALLOWSFW = 0x00000080,

    BSF_SENDNOTIFYMESSAGE = 0x00000100,

    }

     

    [Flags]

    enum BSM

    {

    BSM_ALLCOMPONENTS = 0x00000000,

    BSM_VXDS = 0x00000001,

    BSM_NETDRIVER = 0x00000002,

    BSM_INSTALLABLEDRIVERS = 0x00000004,

    BSM_APPLICATIONS = 0x00000008,

    BSM_ALLDESKTOPS = 0x00000010,

    }

     

    enum BSM_Return

    {

    UnableToBroadcast = -1,

    BROADCAST_QUERY_DENY = 0x424D5144,

    }

     

    [DllImport("user32.dll", SetLastError= true)]

    static extern int BroadcastSystemMessage(BSF dwFlags, ref BSM dwRecipients, UInt32 uiMessage, IntPtr wParam, IntPtr lParam);

     

    #endregion

     

     

    Then call the function:

     

    Code Snippet

     

    BSM recipients = BSM.BSM_ALLCOMPONENTS;

     

    int lRet = BroadcastSystemMessage(BSF.BSF_FORCEIFHUNG, ref recipients, Convert.ToUInt32(WinMessages.WM_CANCELMODE), IntPtr.Zero, IntPtr.Zero);

     

     

    Not sure if this will absolutely work for your situation, but I think it's worth a try.

     

    Dan

    Sunday, May 18, 2008 3:09 PM