Jump to content

How does Windows determine the order in which to shut down processes?


Recommended Posts

I'm trying to block a user-invoked log-off or shutdown from occurring via an AutoIT script I'm using. The purpose of the block is to keep users from trying to "outsmart" The Man by logging off while a mandatory product update is working / is about to work on their system.

This helper app successfully uses WM_QUERYENDSESSION to reject and cancel a shutdown request from the system, but the problem is that I cannot control the order in which Windows tries to shutdown applications. In testing, about 50% of the time the process that is doing the installation I want done is terminated before my little helper app can cancel the shutdown request, which both defeats the purpose of the helper app and also causes problems because now the system cannot (easily) be manually rebooted.

My question is twofold:

1) What property of a process (CreationDate, Handle, etc.) does Windows use to determine its termination order when ending a session?

2) Would it be possible to manipulate that property so that Windows tries to kill my helper app first, thus keeping all other processes running?

Any help is appreciated.

Jeemo

An emoticon is worth a dozen words.

Link to comment
Share on other sites

I'm trying to block a user-invoked log-off or shutdown from occurring via an AutoIT script I'm using. The purpose of the block is to keep users from trying to "outsmart" The Man by logging off while a mandatory product update is working / is about to work on their system.

This helper app successfully uses WM_QUERYENDSESSION to reject and cancel a shutdown request from the system, but the problem is that I cannot control the order in which Windows tries to shutdown applications. In testing, about 50% of the time the process that is doing the installation I want done is terminated before my little helper app can cancel the shutdown request, which both defeats the purpose of the helper app and also causes problems because now the system cannot (easily) be manually rebooted.

My question is twofold:

1) What property of a process (CreationDate, Handle, etc.) does Windows use to determine its termination order when ending a session?

2) Would it be possible to manipulate that property so that Windows tries to kill my helper app first, thus keeping all other processes running?

Any help is appreciated.

Jeemo

Something is not right there according to my understanding, because windows should examine the returns from all processes when it sends out WM_QUERYENDSESSION and then only send the WM_ENDSESSION if no process returns zero. Unless the other apps respond to the request by closing which I don't think they should.

I don't know but maybe Windows sends messages to applications in the order they were started, so if you had a program which started before the other scripts it would help, even if that first program was only to detect the WM_QUERYENDSESSION message and then perhaps close your main app straight away.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

I don't know but maybe Windows sends messages to applications in the order they were started,

I'm pretty sure the case is, as you said, that it sends a request to the applications in the order in which they were started and (barring an objection) shuts them down immediately.

so if you had a program which started before the other scripts it would help

That's my challenge - getting my helper app to pony itself into the "shut me down first" position, so that it can kill the request before Windows can squash my desired installation process. Your suggestion is good, but unfortunately the environment I work in will definitely not accommodate starting this app first for the sake of the installation "maybe" hitting during that login session.

Any other suggestions?

An emoticon is worth a dozen words.

Link to comment
Share on other sites

I'm pretty sure the case is, as you said, that it sends a request to the applications in the order in which they were started and (barring an objection) shuts them down immediately.

That's my challenge - getting my helper app to pony itself into the "shut me down first" position, so that it can kill the request before Windows can squash my desired installation process. Your suggestion is good, but unfortunately the environment I work in will definitely not accommodate starting this app first for the sake of the installation "maybe" hitting during that login session.

Any other suggestions?

I can't think of anything now (and I might never) but Windows doesn't behave as you describe. It only closes programs down if no program has 'objetced' unless I misunderstand rather than you.

WM_QUERYENDSESSION Message

The WM_QUERYENDSESSION message is sent when the user chooses to end the session or when an application calls one of the system shutdown functions. If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.

So are you sure you can't just respond to WM_QUERYENDSESSION by returning zero and maybe that would stop anything closing.
Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.
Link to comment
Share on other sites

You may be right - all I know is that it works intermittently. The user session never ends, but sometimes the main installation is killed, sometimes it is not. I can't imagine why that would be the case unless Windows kills an app as soon as it contacts it and does not get an objection. Here's some of my code:

GUIRegisterMsg($WM_QUERYENDSESSION, "Cancel_Shutdown")
GUICreate("PreventShutdownGUI")
GUISetSTate(@SW_HIDE)

Global $b_ShutdownInitiated = False

While 1
    If $b_ShutdownInitiated = True then
    EndIf

    sleep(10)
WEnd

Func Cancel_Shutdown($hWndGUI, $MsgID, $WParam, $LParam)
    $b_ShutdownInitiated = True
    MsgBox(48 + 8192 + 262144, "Installer", "Ending your user session has been disabled to allow the installation to complete." _
        & @CRLF & @CRLF & "You will be able to shutdown/reboot/logoff once the installation process has completed." , 8)

    Return False
EndFunc

An emoticon is worth a dozen words.

Link to comment
Share on other sites

Ahh, I see where the confusion lies:

If any application returns zero, the session is not ended. The system stops sending WM_QUERYENDSESSION messages as soon as one application returns zero.

In other words, it knocks out each process as it encounters it, but once it hits a process that returns a zero it leaves that and all subsequent processes alone. This is what's happening in my case - sometimes the WM_QUERYENDSESSION request hits my helper app first (yay), sometimes it hits my main installer first (boo).

An emoticon is worth a dozen words.

Link to comment
Share on other sites

  • 1 month later...

Ahh, I see where the confusion lies:

In other words, it knocks out each process as it encounters it, but once it hits a process that returns a zero it leaves that and all subsequent processes alone. This is what's happening in my case - sometimes the WM_QUERYENDSESSION request hits my helper app first (yay), sometimes it hits my main installer first (boo).

You can inform Windows to attempt to shutdown your application first by adding the following API call.

DllCall("Kernel32", "ubyte", "SetProcessShutdownParameters", "dword", 0x400, "dword", 0x000)

--- TTFN

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...