-
-
Save lalibi/3762289efc5805f8cfcf to your computer and use it in GitHub Desktop.
function Set-WindowState { | |
<# | |
.LINK | |
https://gist.github.com/Nora-Ballard/11240204 | |
#> | |
[CmdletBinding(DefaultParameterSetName = 'InputObject')] | |
param( | |
[Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true)] | |
[Object[]] $InputObject, | |
[Parameter(Position = 1)] | |
[ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE', | |
'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED', | |
'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')] | |
[string] $State = 'SHOW', | |
[switch] $SuppressErrors = $false, | |
[switch] $SetForegroundWindow = $false | |
) | |
Begin { | |
$WindowStates = @{ | |
'FORCEMINIMIZE' = 11 | |
'HIDE' = 0 | |
'MAXIMIZE' = 3 | |
'MINIMIZE' = 6 | |
'RESTORE' = 9 | |
'SHOW' = 5 | |
'SHOWDEFAULT' = 10 | |
'SHOWMAXIMIZED' = 3 | |
'SHOWMINIMIZED' = 2 | |
'SHOWMINNOACTIVE' = 7 | |
'SHOWNA' = 8 | |
'SHOWNOACTIVATE' = 4 | |
'SHOWNORMAL' = 1 | |
} | |
$Win32ShowWindowAsync = Add-Type -MemberDefinition @' | |
[DllImport("user32.dll")] | |
public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); | |
[DllImport("user32.dll", SetLastError = true)] | |
public static extern bool SetForegroundWindow(IntPtr hWnd); | |
'@ -Name "Win32ShowWindowAsync" -Namespace Win32Functions -PassThru | |
if (!$global:MainWindowHandles) { | |
$global:MainWindowHandles = @{ } | |
} | |
} | |
Process { | |
foreach ($process in $InputObject) { | |
$handle = $process.MainWindowHandle | |
if ($handle -eq 0 -and $global:MainWindowHandles.ContainsKey($process.Id)) { | |
$handle = $global:MainWindowHandles[$process.Id] | |
} | |
if ($handle -eq 0) { | |
if (-not $SuppressErrors) { | |
Write-Error "Main Window handle is '0'" | |
} | |
continue | |
} | |
$global:MainWindowHandles[$process.Id] = $handle | |
$Win32ShowWindowAsync::ShowWindowAsync($handle, $WindowStates[$State]) | Out-Null | |
if ($SetForegroundWindow) { | |
$Win32ShowWindowAsync::SetForegroundWindow($handle) | Out-Null | |
} | |
Write-Verbose ("Set Window State '{1} on '{0}'" -f $MainWindowHandle, $State) | |
} | |
} | |
} |
I'm having an issue with using your inputobject. It's telling me that its null when I run this from a piped "Get-Process"
Question: Once you "HIDE" a window, its MainWindowHandle becomes 0, ... so how do you make it visible again?
Start-Process 'notepad.exe' # Start notepad.
$hwndBefore = (Get-Process -Name 'notepad').MainWindowHandle # Get main window handle.
Set-WindowStyle -MainWindowHandle $hwndBefore -Style HIDE # Hide it.
$hwndAfter = (Get-Process -Name 'notepad').MainWindowHandle # Handle now = 0
Set-WindowStyle -MainWindowHandle $hwndAfter -Style SHOW # No effect
Modify the code so that BEFORE you minimize it, you store info about the process (PID or ProcessName). That way you can reference it.
Thanks, Dude, working like a charm on Windows 8, I need the alt - tab simulation but I was able to solve my issue minimizing the unwanted app and bring to the front the desired app.
I can't seem to restore a minimized window. Can someone post an example code on how to achieve this?
After the window is minimized, if I do this:
$hwndAfter = (Get-Process -Name 'notepad').MainWindowHandle
I can get the mainwindowhandle just fine. So why Can't I just do this?
Set-WindowStyle -MainWindowHandle $hwndAfter -Style RESTORE
OR this:
Set-WindowStyle -MainWindowHandle $hwndAfter -Style SHOW
?
@chaoscreater RESTORE should work after you minimize a window. It doesn't work when you use HIDE, where MainWindowHandle
becomes 0
.
Updated the code so that it keeps the MainWindowHandle
of the processes (for the current session) it handles. So now (in the same session) you can HIDE
and then SHOW
a window.
The implementation is not that elegant at the moment, it pollutes the global space with a variable (MainWindowHandle
)
Updated the code so that it keeps the
MainWindowHandle
of the processes (for the current session) it handles. So now (in the same session) you canHIDE
and thenSHOW
a window.The implementation is not that elegant at the moment, it pollutes the global space with a variable (
MainWindowHandle
)
Hi, thanks for updating the script. I can't figure out how to use it, I'm getting the following error:
Cannot convert argument "hWnd", with value: "", for "ShowWindowAsync" to type "System.IntPtr": "Cannot convert null to type "System.IntPtr"."
Could you provide an example of how to restore a minimized window please?
Update:
Nevermind, I got it.
$inputobject = get-process -name 'notepad'
Set-WindowState -inputObject $inputobject -State RESTORE
Or like this:
Get-Process notepad | Set-WindowState -State Hide
Get-Process notepad | Set-WindowState -State Show
Keep getting error "Main Window handle is '0' " when trying to run this on spotify, works Fine on notepad though. Maybe something to do with how spotify seems to be made up of 3 processes in task manager.
Image attached to show what I mean.
https://i.ibb.co/71nqXhx/Capture69.jpg
It's good, but although it sets the correct window state on the correct handle, what is still missing in certain $State
s is a command to bring the window to the foreground, e.g. $Win32ShowWindowAsync::SetForegroundWindow($handle) | Out-Null
@Duoquadragesimal, yes it's because of the multiple processes, it should work though. You get an error for each process that doesn't have a main window. I added a -SuppressErrors
flag, so you can call it like this:
Get-Process spotify | Set-WindowState -State Show -SuppressErrors
Get-Process spotify | Set-WindowState -State Hide -SuppressErrors
@Nagidal added a flag for that too -SetForegroundWindow
Get-Process someprocess| Set-WindowState -State Show -SetForegroundWindow
Hmm. When I do this, the program gets hidden, but it does not show again
Get-Process program | Set-WindowState -State Hide -SuppressErrors
then
Get-Process program | Set-WindowState -State Show -SuppressErrors
Any idea?
Hmm. When I do this, the program gets hidden, but it does not show again
Get-Process program | Set-WindowState -State Hide -SuppressErrors
thenGet-Process program | Set-WindowState -State Show -SuppressErrors
Any idea?
You need to execute those two commands in the same session. Otherwise it won't work, since a "hidden" application doesn't have a MainWindowHandle
.
Corrected issues with illegal characters and added pipeline support.