windowspowershellexplorer

Shortcut to pull up all file explorer windows that are open


Hi I'm trying to make a script to open all minimized file explorer windows at the same time. the gpt script I'm using below doesn't work.

$shell = New-Object -ComObject Shell.Application
$shell.Windows() | ForEach-Object {
    if ($_.Name -eq 'File Explorer') {
        $_.Visible = $true
        $_.Document.Focus()
    }
}

I saved the file as text.ps1 and I am running it by creating a shortcut that will have a macro assigned to it. in the location field of the shortcut i have this location:

powershell -ExecutionPolicy Bypass -File "C:\Desktop\text.ps1"

are there changes i need to make to the script, or is what i'm describing not possible to do? thank you!


Solution

  • I doubt the implementation you have with Shell.Application will ever work, leaving aside there is no .Focus() method on .Document. What you can do is call native functions to restore minimized windows, this solution should always work however the implementation is much harder since you're calling low level function with C# implementation.

    Basically what the code below is doing is enumerating all windows with EnumWindows function where the window handle belongs to the specified Process Id passed as argument, with (Get-Process explorer).Id in this case, then minimizes, restores and activates the window.

    Normally, minimizing the window shouldn't be required however from OP's feedback and after testing, it seems that if a different window is overlapping the explorer window simply activating / bring to front doesn't work consistently (also a tiny delay between minimizing and restoring seem to be required).

    Add-Type @'
    using System;
    using System.Runtime.InteropServices;
    using System.Threading;
    
    public static class Native
    {
        private const int SW_SHOWDEFAULT = 10;
        private const int SW_MINIMIZE = 6;
        private const int SW_SHOW = 5;
        private delegate bool EnumWindowsProc(IntPtr hWnd, int lParam);
    
        [DllImport("user32.dll")]
        private static extern bool EnumWindows(
            EnumWindowsProc enumFunc, int lParam);
    
        [DllImport("user32.dll")]
        private static extern uint GetWindowThreadProcessId(
            IntPtr hWnd, out uint lpdwProcessId);
    
        [DllImport("user32.dll")]
        private static extern bool IsWindowVisible(IntPtr hWnd);
    
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowTextLength(IntPtr hWnd);
    
        [DllImport("user32.dll")]
        private static extern IntPtr GetShellWindow();
    
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        private static extern int GetWindowText(
            IntPtr hWnd, char[] lpString, int nMaxCount);
    
        [DllImport("user32.dll")]
        internal static extern bool ShowWindowAsync(IntPtr windowHandle, int nCmdShow);
    
        [DllImport("user32.dll")]
        private static extern bool SetForegroundWindow(IntPtr hWnd);
    
        public static void RestoreWindowByProcessId(uint id)
        {
            IntPtr shellWindowhWnd = GetShellWindow();
            EnumWindows((IntPtr handle, int lParam) =>
            {
                if (handle == shellWindowhWnd)
                {
                    return true;
                }
    
                if (!IsWindowVisible(handle))
                {
                    return true;
                }
    
                uint processId;
                if (GetWindowThreadProcessId(handle, out processId) == 0)
                {
                    return true;
                }
    
                if (processId != id)
                {
                    return true;
                }
    
                int len;
                if ((len = GetWindowTextLength(handle)) == 0)
                {
                    return true;
                }
    
                char[] buffer = new char[len];
                if (GetWindowText(handle, buffer, len + 1) == 0)
                {
                    return true;
                }
    
                Console.WriteLine(string.Format(
                    "Restoring window with Title: '{0}'",
                    new string(buffer)));
    
                // minize the window first
                ShowWindowAsync(handle, SW_MINIMIZE);
                // add a tiny delay (after testing this is required for it to work consistently)
                Thread.Sleep(200);
                // restore window
                ShowWindowAsync(handle, SW_SHOWDEFAULT);
                ShowWindowAsync(handle, SW_SHOW);
                // activate window
                SetForegroundWindow(handle);
                return true;
            }, 0);
        }
    }
    '@
    
    $process = (Get-Process explorer).Id
    [Native]::RestoreWindowByProcessId($process)