[New] CodePlex Project

As I announced recently I have created a Windows Automation PowerShell Snapin project to house this snapin on CodePlex, and added a bunch of features. You should head over there for the download.

Original Post

I’ve been crazy busy the last few weeks, but I’ve been really rather distracted from my main project and it’s past time I got back to it. To really feel like I’ve moved on, I need to write a bunch of articles here and publish a couple of cool apps and some source code so that I can feel like I’ve reached a release point. What I’ve been playing with in all this coding is the new technology that’s been coming out of Microsoft in the last couple months: PowerShell, .NET 3 and WPF, and Windows Vista so you may or may not actually be able to use these apps …

So yeah, anyway … I’ve been playing around with PowerShell cmdlets, and as a shell geek, I couldn’t help wondering why there wasn’t a way to enumerate windows and move them around … so I wrote one. Eventually this will show up in the PowerShell Community Extensions — but I’m posting it here for now because the powershell cmdlet process is pretty interesting.

I started off by writing a wrapper for some of the Win32 APIs, and then a PSSnapIn which provides Get-Window and Remove-Window. When you execute Get-Window, the resulting object is a Win32.Window which has methods for closing, moving, resizing, maximizing and restoring, etc. The Remove-Window cmdlet is just a wrapper to call the Close() method, but it seems to make sense in the PowerShell pipe, since you can pipe the window objects through filters etc.

I still need to finish up the Move-Window cmdlet — it’s an advanced window-organizing feature. Right now it’s only feature is that it can tile windows vertically or horizontally with percentages specified by you. The features there are a little weak, but it’s past time I show you what I mean.

What you would want to do is install the snapin and then try typing these commands one at a time (so you can see the results).


for( $i = 0; $i -lt 3; $i++){notepad}
Get-Window *notepad* > Notepad.txt
notepad Notepad.txt
Get-Window "Untitled - N*" | Move-Window "20%,30%,50%"
ps notepad | Move-Window "20%,30%,20%,30%" 0
(Get-Window *Notepad.txt*).Minimize()
$notes = Get-Window *notepad*
$notes[0].Minimize()
Get-Window | where {$_.ProcessName -eq "notepad" -and -not $_.IsMinimized} | Remove-Window
ps notepad | Remove-Window
 

A little explanation is in order:

  • Obviously the first three lines basically start up a few copies of notepad — three of them empty, one with a text file.
  • The next line shows how Get-Window works with wildcard matching on the window titles … and how Move-Window uses percentage values to organize windows.
  • Then you see that you can pipe the output of Get-Process (aliased as ps) through Move-Window. You can pipe it through Get-Window too, but the important take away here is that Remove-Window and Move-Window can both take processes as input — as long as those processes have actual windows. You’ll also notice that final parameter “0” to cause Move-Window to tile horizontally instead of vertically — “1” is the default.
  • The next three lines are examples of how you can call methods on individual Window objects.
  • And finally, the next-to-last line is just an example of how you can use Where-Object to filter windows, and the last line is just to get rid of the remaining instances of notepad.

You can download Win32.Window for PowerShell (it’s a 7-zip file, you’ll need TugZip or 7-Zip) ... it includes the source (which you can use under any of several open source licenses including Ms-PL, BSD and GPL) and the actual DLL in the bin/Release directory, along with the scripts Install.ps1 and Uninstall.ps1 ;)

Feature requests and code contributions are both welcome!