orbs Posted November 25, 2016 Share Posted November 25, 2016 OnAutoItExitRegister() stopped working for one of my scripts, running on Windows 7 & 10. the registered function stopped executing upon exit. there were many complex modifications and i don't know when it stopped working so checking earlier versions would be troublesome. i did write this simple reproducer: OnAutoItExitRegister('_OnExit') HotKeySet('{F9}', '_UserExit') DirCreate('C:\TEMP') FileWriteLine('C:\TEMP\_OnExitTest.log', @HOUR & ':' & @MIN & ':' & @SEC & @TAB & 'start') While True Sleep(60000) FileWriteLine('C:\TEMP\_OnExitTest.log', @HOUR & ':' & @MIN & ':' & @SEC & @TAB & 'checkup') WEnd Func _UserExit() Exit 9 EndFunc ;==>_UserExit Func _OnExit() FileWriteLine('C:\TEMP\_OnExitTest.log', @HOUR & ':' & @MIN & ':' & @SEC & @TAB & '@exitCode=' & @exitCode & @TAB & '@exitMethod=' & @exitMethod) EndFunc ;==>_OnExit tested on Windows 7: it works. the registered function is executed at manual exit (from the tray menu, and by the assigned hotkey) and at shutdown (the script is running compiled). my original script, however, does not. so i'm starting to eliminate pieces until i figure out the difference between my full script and this reproducer. tested the reproducer on Windows 10: the registered function is executed if i exit the script manually. it does not execute at shutdown. no issue with permissions - the script writes its "start" and "checkup" messages successfully. i even started it as a scheduled task with elevated SYSTEM account - same issue. nothing on the event logs. any ideas? Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
j0kky Posted November 25, 2016 Share Posted November 25, 2016 (edited) That script works in my Win10, even on shutdown. Maybe for some reason, on your OS during shutdown, Windows kills your app instead of close it. If you don't try a solution, it can be useful for you to catch shutdown messages and parse 'em. Edited November 25, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
orbs Posted November 26, 2016 Author Share Posted November 26, 2016 correction: the reproducer shows the same issue (registered function is not executed at shutdown) on both Windows 7 and 10 (and clean VM of server 2012, see below), when run as a scheduled task as elevated SYSTEM account (similar condition as my production script. i even disabled the option "if the running task does not end when requested, force it to stop"). upon exit by Task Scheduler "End" command, @exitMethod=0. when running manually: upon exit by tray menu: @exitMethod=2 upon exit by hotkey: @exitMethod=1 this is all expected. however at shutdown, there is no indication at the log. i also tried on a clean VM of Windows Server 2012 r2. this time even the Task Scheduler "End" command did not log the expected result! only manual exit is OK. i enabled History and i see the proper chain of events. @j0kky, can you elaborate on your shutdown message comment? i read it's about trapping and processing windows messages, but my production script is compiled as console, no GUI whatsoever (not even a tray menu). Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
j0kky Posted November 26, 2016 Share Posted November 26, 2016 (edited) I tested it only running manually with user rights, I don't know its behaviour if started by scheduled task nor with SYSTEM rights. 1 hour ago, orbs said: no GUI whatsoever Elaborating a shutdown message comment only needs an hide window which gives you its handle, this is a working example of intercepting shutdown, uncomment lines if you want to "block" it for a while. ;#Include <WinAPIEx.au3> Global $hForm, $Msg $hForm = GUICreate('MyGUI') GUIRegisterMsg(0x0011, 'WM_QUERYENDSESSION') GUISetState(@SW_HIDE) ;_WinAPI_SetProcessShutdownParameters(0x03FF) While 1 $Msg = GUIGetMsg() WEnd Func WM_QUERYENDSESSION($hWnd, $Msg, $wParam, $lParam) If $hWnd = $hForm Then ;_WinAPI_ShutdownBlockReasonCreate($hForm, 'something') ;Return False Return True EndIf Return 'GUI_RUNDEFMSG' EndFunc ;==>WM_QUERYENDSESSION Edited November 26, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
orbs Posted November 26, 2016 Author Share Posted November 26, 2016 thanks @j0kky, i will test your example. please clarify: instead of using OnAutoItExitRegister(), i need to put my "on exit" commands inside your WM_QUERYENDSESSION() function, before it returns True? instead of creating my own GUI, can i use the handle for the AutoIt hidden window (as demonstrated in the example for AutoItWinGetTitle)? does this window even exist in console mode? Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
j0kky Posted November 26, 2016 Share Posted November 26, 2016 (edited) 27 minutes ago, orbs said: instead of using OnAutoItExitRegister(), i need to put my "on exit" commands inside your WM_QUERYENDSESSION() function, before it returns True? Yes, remember general recommendation for processing message: Warning: blocking of running user functions which executes window messages with commands such as "MsgBox()" can lead to unexpected behavior, the return to the system should be as fast as possible !!! So, if you just need to write a line in a text file, no problem; but if you need more complex elaboration it would be better to set a global variable within WM_QUERYENDSESSION function, return and check for that flag in the main loop. Differently from other messages, WM_QUERYENDSESSION has another disadvantage: each elaboration you have to do, you must complete it as fast as possible, because the system is shutting down and you really have few time. 27 minutes ago, orbs said: instead of creating my own GUI, can i use the handle for the AutoIt hidden window (as demonstrated in the example for AutoItWinGetTitle)? does this window even exist in console mode? I suspected the existence but I didn't know about that hidden window Try for it and let me know! Edited November 26, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
orbs Posted November 30, 2016 Author Share Posted November 30, 2016 using WM_QUERYENDSESSION does not behave well. using the very basic example at post #4, i just added a FileWriteLine before the Return True line. result: at shutdown, the system hangs for a few seconds, then briefly pops-up the screen about a process not closing (or something similar), then immediately shutdown. in any case, no line was written to file. at least there is one plus to this - all test environments behave the same. tested on visible GUI, AutoIt hidden window, running as user and as system - in all conditions, no line was written to file. i'm still testing options, like using _WinAPI_SetProcessShutdownParameters in various ranges. regardless, i would very much like to have OnAutoItExitRegister working again. even if i get WM_QUERYENDSESSION to work, and i obviously can manually call the exit routine upon user request, then the method of closing by ending the task is not covered. it is - or was, at least - detected by OnAutoItExitRegister (where @exitMethod=0). Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
JustSomeone Posted November 30, 2016 Share Posted November 30, 2016 (edited) Can you post bit of the code, few days ago i did something similar, and upon the event i can even manage to connect to a DB, update some records and return for like half an second, so writing a line to a file should not be a problem, at all. Also, you can try and opening the file with FileOpen(), write to it with FileWriteLine() then close the file with FileClose(). Depending on your file, i believe it will be alot faster than passing the filename directly to FileWriteLine(). If your program is intended to write a file upon user's session end, you can just task schedule it, events that i use (and i know working) are System\User32\1074 and system\winlogon\7002. (see attached screenshots 1 and 2). And for action i use the exe (stored in random folder of your choice, screenshot 3). EDIT : i personally believe it's better to taskschedule the logout instead of having something waitining for the event to appear. Screenshot 1 Spoiler Screenshot 2 Spoiler Screenshot 3 Spoiler Edited November 30, 2016 by JustSomeone i'm dumb, added some spoilers not to make the post a mile long ;) Link to comment Share on other sites More sharing options...
orbs Posted November 30, 2016 Author Share Posted November 30, 2016 @JustSomeone, 48 minutes ago, JustSomeone said: Can you post bit of the code code using OnAutoItExitRegister() - see first post. code using WM_QUERYENDSESSION - see post #4, as i mentioned i just added a FileWriteLine (to an existing file, eliminated permissions issue). 50 minutes ago, JustSomeone said: Also, you can try and opening the file with FileOpen(), write to it with FileWriteLine() then close the file with FileClose(). Depending on your file, i believe it will be alot faster than passing the filename directly to FileWriteLine(). FileWriteLine opens and closes a file if a file name is specified. this is clearly mentioned in the help. as for the scheduling option: my production script is running as a scheduled task, run at startup, under the local SYSTEM account. it is constantly monitoring a specific input file, and when that file is generated (by another process), my script analyzes it, write some stats data into a report file, evacuates the input file, and logs the entire operation in a log file. the input file may be generated several times a minute, or none at all for hours. other than background monitoring, i have no way of knowing when the input file is generated, so scheduling it otherwise is of no use. what i need to do on exit is simple - write a line to the log file saying it's exiting, at which time, and with what @exitCode and @exitMethod. then i want to rotate the log file, so the next time my script runs, it begins with a fresh log. this has proven very helpful for later analysis. in case of crash, my script starts with checking the existence of a log file, and rotate it if it exists. this was supposed to be only for crash recovery, because the log should have been rotated on exit. so, although i do have a working solution for log rotation, i lost the info about the script exit conditions. i know it should work; it did work for a while. now it doesn't, and it's not only my production script that is not working, it's the simple reproducer too. 1 hour ago, JustSomeone said: i did something similar did you use OnAutoItExitRegister() or WM_QUERYENDSESSION ? or task scheduling? Signature - my forum contributions: Spoiler UDF: LFN - support for long file names (over 260 characters) InputImpose - impose valid characters in an input control TimeConvert - convert UTC to/from local time and/or reformat the string representation AMF - accept multiple files from Windows Explorer context menu DateDuration - literal description of the difference between given dates Apps: Touch - set the "modified" timestamp of a file to current time Show For Files - tray menu to show/hide files extensions, hidden & system files, and selection checkboxes SPDiff - Single-Pane Text Diff Link to comment Share on other sites More sharing options...
JustSomeone Posted November 30, 2016 Share Posted November 30, 2016 (edited) 21 minutes ago, orbs said: @JustSomeone did you use OnAutoItExitRegister() or WM_QUERYENDSESSION ? or task scheduling? I used pure task scheduling since i did not had an running proccess under the SYSTEM account since startup (i didn't need it). My mistake, i didn't properly read the entire thread. However, it's interesting for me so i'll watch the thread, and read bit more about the matter, if i come up with something, i will post it EDIT: I briefly remember something about GUI stuff (even fake ones) not working / not recieving calls at all under SYSTEM account, but i really can't remember the issue now. I will search for some links. Edited November 30, 2016 by JustSomeone Link to comment Share on other sites More sharing options...
j0kky Posted November 30, 2016 Share Posted November 30, 2016 (edited) @orbs: "AutoitWinGetTitle" trick doen't work in this case, can you try to compile exatly this script and put it on the desktop, run it, then shutdown the OS and see what log.txt reports: #Include <WinAPIEx.au3> Global $hForm, $Msg, $vVar = 0 $hForm = GUICreate("My hidden GUI") GUIRegisterMsg(0x0011, 'WM_QUERYENDSESSION') GUISetState(@SW_HIDE) FileWriteLine("log.txt", "Script started at " & @HOUR & ":" & @MIN & ":" & @SEC) _WinAPI_SetProcessShutdownParameters(0x03FF) _WinAPI_ShutdownBlockReasonCreate($hForm, 'Waiting for FileWriteLine') While 1 $Msg = GUIGetMsg() If $vVar = 1 Then FileWriteLine("log.txt", "Shutting down at " & @HOUR & ":" & @MIN & ":" & @SEC) _WinAPI_ShutdownBlockReasonDestroy($hForm) $vVar = 2 EndIf WEnd Func WM_QUERYENDSESSION($hWnd, $Msg, $wParam, $lParam) If ($hWnd = $hForm) And (Not $vVar) Then $vVar = 1 Return False ElseIf ($hWnd = $hForm) And ($vVar = 2) Then Return True EndIf Return 'GUI_RUNDEFMSG' EndFunc ;==>WM_QUERYENDSESSION In my system it works. Edited November 30, 2016 by j0kky Spoiler Some UDFs I created: Winsock UDF STUN UDF WinApi_GetAdaptersAddresses _WinApi_GetLogicalProcessorInformation Bitwise with 64 bit integers An useful collection of zipping file UDFs Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now