Sign in to follow this  
Followers 0
LxP

Shutdown or restart?

11 posts in this topic

Hi all,

I plan to use OnAutoItExit() to abort the shutdown process via DLLCall() so that I can launch some utilities. I then plan to re-initiate the shutdown after that; however the help file suggests that once I do this I cannot determine whether the user initially wanted to shut down or reboot!

How might I go about having my script aware of this? Is it perhaps possible for the @ExitMethod macro to be extended?

Share this post


Link to post
Share on other sites



I think by the time AutoIt actually terminates, it's already too late to stop the shutdown procedure.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

I think by the time AutoIt actually terminates, it's already too late to stop the shutdown procedure.

if you hit cancel in notepad, with an unsaved open file, it will abort it. autoit is another program, I dont think it would be too late by the same standard that notepad isnt too late.

that autoit might not stop itself shutting down is one thing, but not being able to stop windows is another.

Edited by Hayly

Share this post


Link to post
Share on other sites

Valik, you appear to be right as far as AutoIt is concerned --

While 1
    Sleep(0x7FFFFFFF)
WEnd

Func OnAutoItExit()
    If @ExitMethod < 3 Then Return
    Local $Ret = DLLCall('AdvAPI32', 'None', 'AbortSystemShutdown', 'Str', '')
    MsgBox(0, @Error, 'Call made. ' & $Ret[0])
EndFunc

This code does not prevent shutdown.

I'm somewhat suspicious of your wording though; when you say 'terminate', do you refer to the point after OnAutoItExit() has executed? To this end it should theoretically be possible to cancel the shutdown before this (as Hayly has also noted).

Perhaps I can find a third-party solution to intercept shutdowns and run my AutoIt script, but is there hope for an AutoIt-only solution?

Share this post


Link to post
Share on other sites

By the time AutoIt receives the request to terminate by the OS and begins its exit procedure (calling OnAutoItExit()), it is too late to stop the OS from shutting down.

Is that more explicit?

Hayly, I'm not really concerned about what Notepad does or doesn't do. Without the source code to Notepad to fully understand what it's doing, conjecture and comparison are pointless (Although I can present pseudo-code I would expect to see in Notepad but it is irrelevant, AutoIt isn't Notepad).

I can easily stop Windows from shutting down in about 2 lines of code added to a standard Windows message pump. The problem is, there is no facility in AutoIt for doing the same which consists of catching the WM_QUERYENDSESSION message and returning FALSE.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

Okay, I better understand now: AutoIt receives a Windows message indicating that a system shutdown is requested and if AutoIt doesn't immediately respond with 'no', the shutdown commences. Is that right?

What doesn't make sense to me is that there's an AbortSystemShutdown API call, which implies that it should be possible to stop a shutdown that is in fact in progress (even though some programs will have terminated by this point). However, this API call returns false when I invoke it.

Edit: I'm not trying to pretend that I know much about Windows API calls in case I've fooled anyone. I'm simply searching MSDN for what seems appropriate.

Edited by LxP

Share this post


Link to post
Share on other sites

What you are failing to look at is the related link for "InitSystemShutdown". This will start a shutdown with an optional timer. During the timer countdown, AbortSystemShutdown() can be called to cancel the timer and abort the shutdown. It can not be used to stop a shutdown which is already in progress.

Share this post


Link to post
Share on other sites

According to MSDN, if a timeout value is supplied a visible window is displayed to allow shutdown cancellation:

If dwTimeout is not zero, InitiateSystemShutdown displays a dialog box on the specified computer.

This is something I've never seen which suggests that it's not an oft-used feature. However, as per Hayly's example, an unsaved file in Notepad will not only delay the shutdown process but potentially prevent it if the user hits Cancel.

Is this because Notepad catches the WM_QUERYENDSESSION message and returns FALSE as you mentioned earlier? Would this then mean that the shutdown cannot actually start until all windows have responded to that initial message?

If that's correct then it seems possible that AutoIt could delay responding to this message until it has finished/started processing OnAutoItExit(). Am I completely off the mark?

Share this post


Link to post
Share on other sites

Is this because Notepad catches the WM_QUERYENDSESSION message and returns FALSE as you mentioned earlier? Would this then mean that the shutdown cannot actually start until all windows have responded to that initial message?

Correct.

If that's correct then it seems possible that AutoIt could delay responding to this message until it has finished/started processing OnAutoItExit(). Am I completely off the mark?

There's no way to catch the event with AutoIt. Not from user-code at least. And no, it can't be deferred to OnAutoItExit(). AutoIt begins its exit procedure when it receives WM_ENDSESSION which is sent after all applications have processed WM_QUERYENDSESSION. By this point, the shutdown procedure is already underway and it is too late to abort it.

Share this post


Link to post
Share on other sites

Just so that I'm really clear on what happens: Notepad is open with an unsaved file. The user shuts down the computer. Notepad prompts to save the file. Is it correct to say that at this point Notepad hasn't responded to the WM_QUERYENDSESSION message? That it does so when the user dismisses that prompt?

AutoIt begins its exit procedure when it receives WM_ENDSESSION which is sent after all applications have processed WM_QUERYENDSESSION.

Bingo: AutoIt receives WM_ENDSESSION. WM_ENDSESSION is sent after all applications have processed WM_QUERYENDSESSION. Therefore AutoIt has processed WM_QUERYENDSESSION by this point.

Theoretically, would it be possible for AutoIt to see WM_QUERYENDSESSION as an indication to exit (and therefore fire up OnAutoItExit() at that point, and respond afterwards)? This would provide the least possible hindrance to OnAutoItExit() functionality, e.g. it will be able to quickly run some external programs as necessary. This isn't possible after WM_ENDSESSION has been broadcasted.

Understandably this modification would alter the functionality of scripts that currently use OnAutoItExit() at shutdown. Perhaps this could be introduced as an Opt()?

Share this post


Link to post
Share on other sites

Just so that I'm really clear on what happens: Notepad is open with an unsaved file. The user shuts down the computer. Notepad prompts to save the file. Is it correct to say that at this point Notepad hasn't responded to the WM_QUERYENDSESSION message? That it does so when the user dismisses that prompt?

Ask Microsoft. I don't know how Notepad is implemented.

Theoretically, would it be possible for AutoIt to see WM_QUERYENDSESSION as an indication to exit (and therefore fire up OnAutoItExit() at that point, and respond afterwards)? This would provide the least possible hindrance to OnAutoItExit() functionality, e.g. it will be able to quickly run some external programs as necessary. This isn't possible after WM_ENDSESSION has been broadcasted.

This is an exposition of a fundamental flaw in AutoIt's GUIs. The best solution to this problem is for AutoIt's GUIs to support capturing all messages instead of what are deemed "important". Then it would be trivial to institute a dummy window just so the program can have a message pump and thus catch the WM_QUERYENDSESSION message and respond to it. This is the de facto standard way of catching system messages of this nature. However, due to the overly limited nature of AutoIt's GUI, it's not possible to do this at this time. The "correct" way should be the only way supported so until AutoIt's GUI stuff is fixed, what you are trying to achieve is not do-able in a conventional manner.

Understandably this modification would alter the functionality of scripts that currently use OnAutoItExit() at shutdown. Perhaps this could be introduced as an Opt()?

Opt is bad. It has been abused and is a very dirty thing. Its become a crutch for some less than ideal design decisions.

Share this post


Link to post
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
Sign in to follow this  
Followers 0