Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <#
- .SYNOPSIS
- Start a process and set the window to a given position and size.
- .DESCRIPTION
- Starts a process using Start-Process cmdlet and set the windows position and size afterwards using SetWindowPos.
- Any excess parameter will be passed to StartProcess. In case you want to set X, you must also set Y and vice
- versa. Same for width and height.
- Please be aware of programs that store their window position and size. You may not be able to get them back easily
- if you place them outside of your displays range.
- .PARAMETER FilePath
- This parameter specifies the executable file that will be passed to Start-Process. This is a mandatory parameter
- for Start-ProcessAndSetWindow because it is also the only mandatory parameter for Start-Process. This way you will
- be forced to use it.
- .PARAMETER PosX
- Specifies the window's PosX position. PosX will be ignored if PosY has not been set.
- .PARAMETER PosY
- Specifies the window's PosY position. PosY will be ignored if PosX has not been set.
- .PARAMETER Width
- [Optional] Specifies the window's width. Width will be ignored if Height has not been set.
- If set, the value must be lesser or equal to 0 to have any effect.
- .PARAMETER Height
- [Optional] Specifies the window's height. Height will be ignored if Width has not been set.
- If set, the value must be lesser or equal to 0 to have any effect.
- .PARAMETER StartProcessParameters
- [Optional] Any excess parameters will be passed to Start-Process
- .NOTES
- Name: Start-ProcessAndSetWindow
- Author: Thorsten Windrath, https://www.windrath.com
- Version History
- 1.0//Thorsten Windrath - 05/24/2016
- - Initial build
- #>
- function global:Start-ProcessAndSetWindow()
- {
- [CmdletBinding()]
- param
- (
- [Parameter(Mandatory = $true, Position = 0)]
- [string] $FilePath,
- [Parameter(Mandatory = $true)]
- [int] $PosX,
- [Parameter(Mandatory = $true)]
- [int] $PosY,
- [Parameter(Mandatory = $false)]
- [int] $Height = -1,
- [Parameter(Mandatory = $false)]
- [int] $Width = -1,
- [Parameter(Mandatory = $false, ValueFromRemainingArguments=$true)]
- $StartProcessParameters
- )
- # Invoke process
- $process = "Start-Process -FilePath $FilePath -PassThru $StartProcessParameters" | Invoke-Expression
- # We need to get the process' MainWindowHandle. That's not the processes handle or Id!
- if($process -is [System.Array]) { $procId = $process[0].Id } else { $procId = $process.Id }
- # ... fallback in case something goes south (wait up to 5 seconds for the process to launch)
- $i = 50
- # ... Start looking for the main window handle. May take a bit of time for the window to show up
- $mainWindowHandle = [System.IntPtr]::Zero
- while($mainWindowHandle -eq [System.IntPtr]::Zero)
- {
- [System.Threading.Thread]::Sleep(100)
- $tmp = Get-Process -Id $procId -ErrorAction SilentlyContinue
- if($tmp -ne $null)
- {
- $mainWindowHandle = $tmp.MainWindowHandle
- }
- $i = $i - 1
- if($i -le 0)
- {
- break
- }
- }
- # Once we grabbed the MainWindowHandle, we need to use the Win32-API function SetWindowPosition (using inline C#)
- if($mainWindowHandle -ne [System.IntPtr]::Zero)
- {
- $CSharpSource = @"
- using System;
- using System.Runtime.InteropServices;
- namespace TW.Tools.InlinePS
- {
- public static class WindowManagement
- {
- [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
- public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);
- public const int SWP_NOSIZE = 0x01, SWP_NOMOVE = 0x02, SWP_SHOWWINDOW = 0x40, SWP_HIDEWINDOW = 0x80;
- public static void SetPosition(IntPtr handle, int x, int y, int width, int height)
- {
- if (handle != null)
- {
- SetWindowPos(handle, 0, x, y, 0, 0, SWP_NOSIZE | SWP_HIDEWINDOW);
- if (width > -1 && height > -1)
- SetWindowPos(handle, 0, 0, 0, width, height, SWP_NOMOVE);
- SetWindowPos(handle, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW);
- }
- }
- }
- }
- "@
- Add-Type -TypeDefinition $CSharpSource -Language CSharp -ErrorAction SilentlyContinue
- [TW.Tools.InlinePS.WindowManagement]::SetPosition($mainWindowHandle, $PosX, $PosY, $Width, $Height);
- }
- else
- {
- throw "Couldn't find the MainWindowHandle, aborting (your process should be still alive)"
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement