-
-
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' |
Hi, what is the best way to minimize a window if the process name has a period. The process looks like this name_1.0 But the script runs very well otherwise. Thank you very much for that
I am going to ask the dumb question: how should this be invoked? I've tried
> Get-Process *PowerShell* | Set-WindowState -State "SHOW"
and nothing happens. I've got three or four hidden PowerShell windows, but no dice. I then pulled a specific PID (say, 3372) and passed it like
> Get-Process -id 3372 | Set-WindowState -State "SHOW"
and still didn't see any response. I know the script's doing something because if I pass -PassThru
I get a value of MainWindowHandle
. I am tempted to think I'm getting the MainWindowHandle
value for the window in which I'm invoking it. But I just don't grok PowerShell script parameters I guess.
Is it possibly that MainWindowHandle
is set depending on the way in which the shell was invoked? Like, I've got a non-zero integer value for one of my PowerShell processes, but all the others have a value of zero.
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! Thank you very much Nora-Ballard for this code.
I've found once window has MainWindowHandle = 0, you cannot handle it or bring it back. In example: "SystemSettings" process startis with MainWindowHandle = 0 and does not respond to MINIMIZE. Same, if you send a HIDE handle to a process, you cannot get it back even when the process is there.
Haven't found a way to sort this. Thanks.
Hi! Thank you very much Nora-Ballard for this code.
I've found once window has MainWindowHandle = 0, you cannot handle it or bring it back. In example: "SystemSettings" process startis with MainWindowHandle = 0 and does not respond to MINIMIZE. Same, if you send a HIDE handle to a process, you cannot get it back even when the process is there.
Haven't found a way to sort this. Thanks.
You can check my fork. I store the MainWindowHandle
s in a .json
file in "$env:APPDATA\WindowHandles.json"
and restore them every time the script is run. These entries are cleared after a threshold (default = 24h).
I don’t think so, at least not with the API call that is being used currently. We are just calling an existing Windows API function and giving it values that it accepts.