Ok, so I found a solution that worked for me; a tool called AutoHotkey_L and a script made according to these threads on the AutoHotkey forums.
This is the code I use and suggest reading AutoHotkey commands in the documentation. I tweak the code when I find out what it actually does, but for now it works. :)
#NoEnv #Persistent SendMode Input SetWorkingDir %A_ScriptDir% SetTimer, RunBeforeShutdown, Off Gui,+LastFound hwnd:=WinExist() DllCall("ShutdownBlockReasonCreate","Uint",hwnd,"Str","") DllCall("kernel32.dll\SetProcessShutdownParameters", UInt, 0x4FF, UInt, 0) ;puts us first in line for getting the shutdown call, i guess? OnMessage(0x11, "WM_QUERYENDSESSION") Return WM_QUERYENDSESSION(wParam, lParam) { ENDSESSION_Logoff = 2147483648 If (lParam == ENDSESSION_Logoff) { global EventType = "Logoff" } Else { global EventType = "Shutdown" ;no way to distinguish between shutdown and restart } SetTimer, RunBeforeShutdown, On Return false } runBeforeShutdown: SetTimer, RunBeforeShutdown, Off Sleep, 1000 SendInput, {ENTER} ; gets us past the 'Force shudown' screen Sleep, 1000 #SingleInstance, Force DllCall("ShutdownBlockReasonDestroy","Uint",hwnd) ; **** Your commands go here **** RunWait shutdown.bat ; ******** If (EventType == "Logoff") { Shutdown, 0 } Else { Shutdown, 1 } Reload Return
So, now it only distinguishes between exits and shutdowns, but this post has a simple graphical interface in HTML, which allows the user to choose whether they want to reboot, hibernate, etc.
In my case, it is normal to interrupt the shutdown and run the batch file regardless of whether VMware works or not, but you can set a condition for it, for example:
IfWinExist, ahk_class VMPlayerFrame { SetTimer, RunBeforeShutdown, On Return false } Else { Return true }
I already had problems with this script, for example, when the host slowed down so much (memory leak) that the "Force shudown" screen did not appear in time for the script to close it. And this is likely to benefit from tracking the number of attempts so that it can force-disconnect if the first attempt fails.
Good enough, at least. And I don’t even need virtualization for my project, but I hope this can help someone else. Alternative solutions are still very welcome.