7

I am writing the following code to close all explorer windows with PowerShell:

(New-Object -comObject Shell.Application).Windows() |
 ? { $_.FullName -ne $null} |
 ? { $_.FullName.toLower().Endswith('\explorer.exe') } | % { $_.Quit() }

But it does not close out all the open windows. Instead, it closes only RoundDown(N/2)+1 windows, and leaves RoundUp(N/2)-1 windows open.

Can anyone help with this?

CB.
  • 58,865
  • 9
  • 159
  • 159
Wayne Z
  • 73
  • 1
  • 3

3 Answers3

15

I think there's something in the pipeline that goes wrong. This code works:

$a = (New-Object -comObject Shell.Application).Windows() |
 ? { $_.FullName -ne $null} |
 ? { $_.FullName.toLower().Endswith('\explorer.exe') } 

 $a | % {  $_.Quit() }
CB.
  • 58,865
  • 9
  • 159
  • 159
  • 7
    Classic issue with modifying the collection while you are walking its contents. By killing explorer.exe instances, Windows is updating the collection while you're still walking it. That usually results in badness. :-) One common work around is to walk the collection in reverse but the solution you propose works fine as well. – Keith Hill Jul 19 '13 at 22:06
  • To clarify, you always need to be careful using loops to delete items out of an array because when you delete item [0], the item [1] moves to [0]. The loop then moves on to the next number as it does not realise the array has been rearranged. This solution takes a snapshot of the processes so when one is killed it is not deleted from the array the loop is working on. – Deadly-Bagel May 13 '15 at 11:25
  • 1
    Something has changed since Windows `1909` version as I tried this. I cannot seem to fix it though. – Ste Jan 18 '20 at 14:54
3
Stop-Process -Name explorer

Kill all related processes

weiya ou
  • 2,730
  • 1
  • 16
  • 24
1

As per @ste's comment, the accepted answer may have stopped working after windows updates.

I've solved it with something similar in Powershell.

Watchout though as I've assumed any explorer processes with a window title are folders. This might not always be the case (eg maybe if copying files)

get-process | ?{ $_.ProcessName -eq 'Explorer' } | ?{ "" -ne $_.MainWindowTitle } | Stop-Process
JonoB
  • 343
  • 1
  • 9