RestartExplorer() : Updated version

Post your working scripts, libraries and tools for AHK v1.1 and older
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

RestartExplorer() : Updated version

20 Sep 2020, 12:54

Code: Select all

RestartExplorer( WaitSecs:=10 ) { ; requires OS Vista+    ; v2.10 by SKAN on CSC7/D39N
Local PID, Explorer, ID:=WinExist("ahk_class Progman")  ; @ tiny.cc/restartexplorer2
  WinGet, PID, PID
  WinGet, Explorer, ProcessPath
  PostMessage, 0x5B4, 0, 0,, ahk_class Shell_TrayWnd ; WM_USER+436
  Process, WaitClose, %PID%, % ( PID ? WaitSecs : (WaitSecs:=0) )
  If (PID && !Errorlevel)
    Run, %Explorer%
  WinWait, ahk_class Progman,, %WaitSecs%
Return (WinExist()!=ID)
}
 
Usage: RestartExplorer() returns true when successful.
My Scripts and Functions: V1  V2
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: RestartExplorer() : Updated version

20 Sep 2020, 15:55

thanks for sharing...
setting WaitSecs to 0 or 1 gives undesired results on two computers, Win7 and Win10 both Ahk U32, where explorer doesn't start back up... Not sure if there is a chase condition going on but I will try to test it on a super slow computer with higher times
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: RestartExplorer() : Updated version

20 Sep 2020, 17:06

gwarble wrote: setting WaitSecs to 0 or 1 gives undesired results on two computers, Win7 and Win10 both Ahk U32, where explorer doesn't start back up...
WaitSecs parameter exists so that it can be increased.. not decreased.
For me it takes less than 500ms for the function to return, if I call SetWinDelay -1 before restarting.
On a slower WIn 7 laptop it takes about 5 to 7 secs depending on processer load.
It doesn't matter if RestartExplorer(100) is done on both machines. It will take only the minimum time.

Let me explain.
Say you boot into a computer and open 3 file explorer windows.
There will be minimum 5 explorer windows with following class names
  • Progman (Desktop)
    Shell_TrayWnd (Taskbar)
    Shell_SecondaryTrayWnd (extra Taskbar on multi-monitor setups)
    CabinetWClass
    CabinetWClass
    CabinetWClass
The above windows have to be closed from bottom to up and here is the thing:

Run, C:\Windows\explorer.exe will launch "File explorer" when ahk_class Progman exists.
Run, C:\Windows\explorer.exe will launch ahk_class Progman itself when it doesn't exist.

If Run, C:\Windows\explorer.exe is done before Progman exits, a "File explorer" will be launched
while Progman disappears and the system will become unstable requiring a log-off.

So, the function does this

Code: Select all

  Process, WaitClose, %PID%, %WaitSecs%
  If (Errorlevel) ;  <-- Timed out !!
        Return 0  ;   so cancel out   ...
  Run, %ExpPath% ; and definitely do not run this
 

Do ask, if you need more explanation. :thumbup: :)
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: RestartExplorer() : Updated version

20 Sep 2020, 18:07

makes sense... thanks for the explanation

edit: I was able to get the same result with a simple test script and default WaitSecs:=10
I will try setting the default to 100 and see if the problem reoccurs
Last edited by gwarble on 20 Sep 2020, 22:05, edited 1 time in total.
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
malcev
Posts: 1769
Joined: 12 Aug 2014, 12:37

Re: RestartExplorer() : Updated version

20 Sep 2020, 19:30

Code: Select all

WinGet, pid, pid, ahk_class Shell_TrayWnd
hExplorer := DllCall("OpenProcess", "int", PROCESS_TERMINATE := 1, "uint", false, "uint", pid, "ptr")
DllCall("TerminateProcess", "ptr", hExplorer, "uint", 2)
DllCall("CloseHandle", "ptr", hExplorer)
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: RestartExplorer() : Updated version

21 Sep 2020, 01:47

Hi @malcev
malcev wrote:
20 Sep 2020, 19:30

Code: Select all

WinGet, pid, pid, ahk_class Shell_TrayWnd
hExplorer := DllCall("OpenProcess", "int", PROCESS_TERMINATE := 1, "uint", false, "uint", pid, "ptr")
DllCall("TerminateProcess", "ptr", hExplorer, "uint", 2)
DllCall("CloseHandle", "ptr", hExplorer)
IIRC, I've seen that solution online. That's rather a very forceful method.

@gwarble :
If you do Ctrl+Shift + Right click on taskbar, you will see "Exit Explorer" as the last item
in the context menu.
PostMessage, 0x5B4, 0, 0,, ahk_class Shell_TrayWnd ; WM_USER+436 is equivalent of selecting that menu item.
 
editexp.png
editexp.png (35.49 KiB) Viewed 3688 times

 
You could experiment as follows:

Keep a command prompt open.
Keep a task manager open.
Exit Explorer from taskbar see if how long explorer.exe takes to disappear from task manager
Run explorer.exe from command prompt to launch desktop.
 
:thumbup:
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: RestartExplorer() : Updated version

21 Sep 2020, 23:25

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
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: RestartExplorer() : Updated version

22 Sep 2020, 03:17

gwarble wrote: 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
Another alternate way is to simulate a log-off with

Code: Select all

PostMessage, 0x16, 1,0x1,, ahk_class Progman ; WM_ENDSESSION, True, ENDSESSION_CLOSEAPP
That works in Win 8.1 and Win 10 but any open "File explorer" should be closed before calling this.
Unfortunately In Win 7, the system logs-off and is why I've avoided this.
gwarble wrote: 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).
I will test this. I have never been able to run explorer.exe elevated.

Do share your findings.. :thumbup:
User avatar
gwarble
Posts: 524
Joined: 30 Sep 2013, 15:01

Re: RestartExplorer() : Updated version

22 Sep 2020, 08:35

I haven't either before! I will test again on Win10, but my simple test with your initial function runs explorer elevated on my two Win7 setups.

Code: Select all

;run as admin
F1::RestartExplorer()
Edit: not on Win10...
EitherMouse - Multiple mice, individual settings . . . . www.EitherMouse.com . . . . forum . . . .
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: RestartExplorer() : Updated version

26 Sep 2020, 15:53

gwarble wrote: Edit: not on Win10...
Ah! Thank you. :thumbup:

Code updated.
Removed XP check
Simplified code.

Message WM_USER+436 works for me in WIN 7, 8.1 and 10

A few posts have been split into a separate topic: https://www.autohotkey.com/boards/viewtopic.php?t=81514
newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

Re: RestartExplorer() : Updated version

27 Feb 2022, 21:43

SKAN wrote:
20 Sep 2020, 12:54

Code: Select all

RestartExplorer( WaitSecs:=10 ) { ; requires OS Vista+    ; v2.10 by SKAN on CSC7/D39N
Local PID, Explorer, ID:=WinExist("ahk_class Progman")  ; @ tiny.cc/restartexplorer2
  WinGet, PID, PID
  WinGet, Explorer, ProcessPath
  PostMessage, 0x5B4, 0, 0,, ahk_class Shell_TrayWnd ; WM_USER+436
  Process, WaitClose, %PID%, % ( PID ? WaitSecs : (WaitSecs:=0) )
  If (PID && !Errorlevel)
    Run, %Explorer%
  WinWait, ahk_class Progman,, %WaitSecs%
Return (WinExist()!=ID)
}
 
Usage: RestartExplorer() returns true when successful.
Hi,

may I understand the advantage of this code compared to below, especially when it takes much longer to refresh and also opens the win explorer (which I don't want?):

Code: Select all

RunWait taskkill /F /IM explorer.exe 
Run explorer.exe
return
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: RestartExplorer() : Updated version

27 Feb 2022, 21:54

Hi @newcod3r
Turning off a machine rather doing a proper shutdown is super faster but one will have to face repercussions owing to "unfinished business" of OS.
Likewise, Taskkill should be used only when there are no other means to exit a process.
newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

Re: RestartExplorer() : Updated version

27 Feb 2022, 22:03

understood. in this case, how do I prevent the script from launching Win Explorer at the end? I can't just delete

Code: Select all

Run, %Explorer%
right?
User avatar
SKAN
Posts: 1551
Joined: 29 Sep 2013, 16:58

Re: RestartExplorer() : Updated version

27 Feb 2022, 22:21

newcod3r wrote:
27 Feb 2022, 22:03
understood. in this case, how do I prevent the script from launching Win Explorer at the end? I can't just delete

Code: Select all

Run, %Explorer%
right?
I need to test in all OS.
Win Explorer doesn't launch for me after a restart. (Win 10)
newcod3r
Posts: 505
Joined: 30 Sep 2021, 02:16

Re: RestartExplorer() : Updated version

27 Feb 2022, 22:31

ah ok. I'm on win 11 currently.

Return to “Scripts and Functions (v1)”

Who is online

Users browsing this forum: No registered users and 74 guests