-
-
Save Nora-Ballard/11240204 to your computer and use it in GitHub Desktop.
function Set-WindowState { | |
param( | |
[Parameter()] | |
[ValidateSet('FORCEMINIMIZE', 'HIDE', 'MAXIMIZE', 'MINIMIZE', 'RESTORE', | |
'SHOW', 'SHOWDEFAULT', 'SHOWMAXIMIZED', 'SHOWMINIMIZED', | |
'SHOWMINNOACTIVE', 'SHOWNA', 'SHOWNOACTIVATE', 'SHOWNORMAL')] | |
[Alias('Style')] | |
[String] $State = 'SHOW', | |
[Parameter(ValueFromPipelineByPropertyname='True')] | |
[System.IntPtr] $MainWindowHandle = (Get-Process –id $pid).MainWindowHandle, | |
[Parameter()] | |
[switch] $PassThru | |
) | |
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); | |
“@ -name “Win32ShowWindowAsync” -namespace Win32Functions –passThru | |
} | |
PROCESS | |
{ | |
$Win32ShowWindowAsync::ShowWindowAsync($MainWindowHandle, $WindowStates[$State]) | Out-Null | |
Write-Verbose ("Set Window State on '{0}' to '{1}' " -f $MainWindowHandle, $State) | |
if ($PassThru) | |
{ | |
Write-Output $MainWindowHandle | |
} | |
} | |
END | |
{ | |
} | |
} | |
Set-Alias -Name 'Set-WindowStyle' -Value 'Set-WindowState' |
hey Nora - really great work here!
I ran into a few issues getting the gist to run on my Win 11 setup. To make it easier than finding minor changes in this thread, I posted a new repo here for your consideration. https://github.com/surfaceowl/Set-WindowState.ps1
There are three files there to help see the changes in steps-
- Set-WindowState.ps1 -- directly from Nora's gist, for reference / diffs
- Set-WindowState-v2-basic-fixes.ps1 -- corrects quote and dash chars that cause powershell errors on my install
- Set-WindowState-v3-style-suggestions.ps1 -- building on v2, some minor order/style changes
Using Set-WindowState-v2-basic-fixes.ps1 as an example, once this function is referenced in your powershell profile you can run from your terminal anywhere with something like: Get-Process *Evernote* | Set-WindowState -State "MINIMIZE" ...that just finds all the instances of a process and then minimizes
This is super helpful for managing annoying recurring tasks in Task Scheduler you can put this in a script file (e.g. paste cmd above into a file named minimize_evernote.ps1
and setup a new task in Task Scheduler. The cmd below will run the script silently, importantly avoiding a quick pop-up or flash of a powershell window that some may find annoying or worrisome (especially if run at startup). Configure the task with:
Program/script: cmd
Add arguments:
/c start /min "" Powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "C:\Users\chris\dev\powershell_scripts\minimize_evernote.ps1"
(of course, change the line above to match whatever path and filename used on your system)
Hi All,
I'm going to necropost this one, since there's a bunch of links leading here from StackOverflow, and search engines also hit here.
First of all, thank you to @Nora-Ballard - this has been a huge help, as I needed this specific funcionality for one of my scripts.
Now, at least on my install - there's a couple of issues with the script as it stands, which I assume might just be due to newer versions of powershell.
Get-Process -id ID | Set-WindowState
worksGet-Process -id ID | Set-WindowState -State "MINIMIZED"
doesn't. It defaults to the $pid of the powershell window itself which is what I assume is happening to @muraii. Which is a really weird symptom. That and hidden windows may or may not haveMainWindowHandle
, think they are not supposed to, but behaviour seems inconsistent.Start-Process
the $MainWindowHandle value will be zero and nothing useful will happen e.g.:(Start-Process Notepad -passthru).ID | Set-WindowState -State "MINIMIZE"
. Will have $MainWindowHandle == 0 and nothing will happen, If the #1 is not fixed - it will minimize powershell window itself.In light of that - i did a couple adjustments.:
For #1 - processing of pipe input has been moved to
PROCESS
section out ofBEGIN
section.For #2 - I've used
WaitForInputIdle()
to wait until the process has initialized and has MainWindowHande at all. Still doesn't work with some programms that launch some sort of startup .exe that then closes and leaves the main app open (e.g. steam, thunderbird). This can be resolved by adding a recursive function to go over the child processes. And then when calling Set-Windowstate - we can iterate over those. But I've not integrated that yetAnd the actual full code that I've used to address the issues I've encountered
I've also removed the aliases while investigating the issues I had, but that should be easy to add back if one wants them.