I like to make little videos to go with my blog posts, and today I’ve been looking for a way to resize my browser window to a consistent size for recording.
Google immediately turned up this little beauty in the TechNet Script Center:
But when I tried it out:
Set-Window -ProcessName msedge -Width 1024 -Height 768
…I got a scary error:
Cannot convert argument "hWnd", with value: "System.Object[]", for "GetWindowRect" to type "System.IntPtr": "Cannot convert the "System.Object[]" value of type "System.Object[]" to type "System.IntPtr"."
At C:\Git\PowerShell\Set-Window.ps1:91 char:9
+ $Return = [Window]::GetWindowRect($Handle,[ref]$Rectangle)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodException
+ FullyQualifiedErrorId : MethodArgumentConversionInvalidCastArgument
Here are the relevant lines from the function:
$Handle = (Get-Process -Name $ProcessName).MainWindowHandle
$Return = [Window]::GetWindowRect($Handle,[ref]$Rectangle)
A bit of exploring shows that one of the msedge processes is very different from the others:
$msedge = Get-Process msedge
$msedge
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName
------ ----- ----- ------ -- -- -----------
10 1.77 2.64 0.03 904 1 msedge
19 17.69 30.85 0.34 4044 1 msedge
57 128.71 150.07 57.81 5000 1 msedge
83 185.82 182.69 38.77 8840 1 msedge
29 47.08 75.16 9.78 9548 1 msedge
83 82.12 128.55 171.92 11304 1 msedge
22 27.96 41.45 0.41 11596 1 msedge
20 21.31 38.14 2.47 12664 1 msedge
49 303.89 156.82 116.14 12828 1 msedge
24 29.71 48.62 1.52 14788 1 msedge
26 21.57 31.14 25.20 15904 1 msedge
56 132.80 157.91 76.39 15976 1 msedge
20 19.50 33.82 0.27 16360 1 msedge
16 11.88 19.46 0.05 16416 1 msedge
34 59.82 89.91 3.55 17300 1 msedge
29 48.37 76.49 3.34 17884 1 msedge
22 25.07 42.07 0.41 18408 1 msedge
27 51.70 78.73 5.69 18492 1 msedge
26 39.59 60.88 0.81 18520 1 msedge
28 54.87 73.89 18.56 19080 1 msedge
47 108.27 135.33 26.95 19888 1 msedge
$msedge.MainWindowHandle
0
0
0
0
0
4326398
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
This was my first solution, which works fine:
# Only get non-zero handles
$Handle = (Get-Process -Name $ProcessName).MainWindowHandle | Where-Object {$_.ToInt32() -gt 0}
# The Handles have type IntPtr. Without .ToInt32() you get this error:
# Cannot compare "0" because it is not IComparable
But after a bit of poking around, I think this is a little better:
# Only get process whose parent is explorer
$Handle = (Get-Process -Name $ProcessName | Where-Object {$_.Parent.ProcessName -eq 'explorer'}).MainWindowHandle