I tend to leave my computer on for weeks at a time. The only issue I have with this is that the task bar flakes out after a number of days. Usually this takes the form of not rendering icons in the start menu. It can go as far as just not rendering anything in the start menu. Restarting the Explorer process works well to fix this in Windows 10.
Rather than manually trying to figure out which one of the
explorer.exe tasks is handling the task bar and restarting it, I’d like to write a powershell script that does this.
How would I programmatically determine which instance of
explorer.exe is currently responsible for the task bar?
A slightly more concise alternative to veefu’s helpful answer:
Note: Similarly, no guarantees:
The method relies on the
.MainWindowTitle property of the taskbar-owning File Explorer instance reflecting the taskbar‘s window title, which happens to be empty, unlike the title of actual File Explorer windows – this appears to be the case on at least Windows 10 and Windows 7 (haven’t tried others):
Get-Process explorer | ? MainWindowTitle -eq '' # returns taskbar-owning Explorer process
If other users could be logged on and you must limit the processes inspected to the current user’s, run the following from an elevated console:
Get-Process -IncludeUserName explorer |
? MainWindowTitle -eq '' |
? UserName -eq (whoami)
Robust, but more complex approach:
Add-Member -MemberDefinition, you can define a helper type and method that finds the handle (HWND) of the process that owns the taskbar window, utilizing a P/Invoke signature to call a Windows API functions; note that you’ll incur an on-demand compilation performance penalty the first time you call this in a session.Tip of the hat to Klaidonis for helping me simplify the code.
# Define a helper type and method for getting a window's handle
# (HWND) by its class name and title.
$helperType = Add-Type -PassThru -Name "WinApiHelper$PID" -MemberDefinition @'
public static extern IntPtr FindWindow(string lpszClass, string lpszWindow);
# Locate the explorer.exe process that created the taskbar,
# via window class "Shell_TrayHwnd" and an empty title.
Get-Process explorer |
? MainWindowHandle -eq ($helperType::FindWindow("Shell_TrayWnd", ''))
As for when multiple File Explorer processes may exist (based on trial and error – do tell me if I got things wrong):
- If multiple users are logged on interactively (whether remotely or not), each such user may have one or more Explorer processes running, as described below.
- An interactively logged-on user has at least one Explorer process, which owns the taskbar and the desktop – it may or may not have actual File Explorer windows open; let’s call it the Explorer shell process.
- If File Explorer’s
Launch folder windows in a separate processview option is:
- OFF (the default): all windows you create interactively are owned by the Explorer shell process – no new process is created.
- ON: the first window you create interactively spawns one new Explorer process and all subsequently opened windows are then owned by that same new process.
- In other words: If you only ever open File Explorer windows interactively, you either have one (
Launch folder windows in a separate processOFF) or up to two (
Launch folder windows in a separate processON) Explorer processes.
If you create Explorer windows programmatically, it is a different story – see next point.
- Irrespective of the
Launch folder windows in a separate processview setting, new Explorer processes can be created programmatically:
- For instance, a command such as
explorer /e,c:\creates a new Explorer process every time.
- For instance, a command such as