i guess my confusion arose from expecting a forceful close if polite closing didn't work... I'd like to replace the taskkill in my version below but
PostMessage, 0x111, 518, 0,, ahk_class Shell_TrayWnd doesn't seem to do it for me on this Win10 setup... I will do more testing
One other difference, that could be a useful feature but probably not in a "restart" function (maybe "ElevateExplorer()") is that if you run your function from a script running as administrator, explorer restarts as administrator (which means all programs/scripts ran are elevated). In most cases I would want it to start unelevated no matter the calling script, but I think making this an option would be useful in either function:
Code: Select all
RestartExplorer(delay=-1) {
If (A_OSVersion != "WIN_XP") {
WinGet, PID, PID, ahk_class Shell_TrayWnd
PostMessage, 0x5B4, 0, 0, , ahk_class Shell_TrayWnd ; WM_USER + 0x1B4
PostMessage, 0x111, 518, 0,, ahk_class Shell_TrayWnd ; thanks SKAN, but needs more testing on win10
} Else {
WinGet, PID, PID, ahk_class Progman
PostMessage, 0x012, 0, 0, , ahk_class Progman ; WM_QUIT = 0x12 ; ExitExplorer2
PostMessage, 0x012, 0, 1, , ahk_class Progman ; WM_QUIT = 0x12 ; ExitExplorer1
PostMessage, 0x012, 0, 0, , ahk_class Shell_TrayWnd ; WM_QUIT = 0x12
}
RunWait taskkill /F /IM explorer.exe,, Hide
Sleep, %delay%
If ((A_OSVersion != "WIN_XP") && A_IsAdmin) {
hMod := DllCall("LoadLibrary", Str, "wdc.dll", Ptr)
WdcRunAsIU := DllCall("GetProcAddress", Ptr, hMod, AStr, "WdcRunTaskAsInteractiveUser", Ptr)
DllCall(WdcRunAsIU, WStr, "%windir%\explorer.exe", Ptr, 0, UInt, 9, UInt)
DllCall("FreeLibrary", Ptr, hMod)
} Else
Run %A_WinDir%\explorer.exe, %A_WinDir%\system32, UseErrorLevel
}
personally I would want forceful close if process, waitclose didn't work... but I haven't found a method as reliable across xp/7/10 as taskkill above (i will be testing malcev's recommendation as well)
at the very least I think your restarting method could benefit from
WdcRunTaskAsInteractiveUser