funkywindowsOne feature of the Visual Studio SDK that isn’t available in the standard IDE interface is Window Configurations.  Visual Studio can remember where all of your windows are located and recall their visibility and positioning at your whim.

StudioShell exposes this as a first-class feature on the DTE: drive.  You can view the list of defined window configurations using the get-childitems cmdlet:

> get-childitems dte:/windowConfigurations Location: PSDTE::dte:\windowconfigurations Available Operations: d+ < Name ---------- ---- ~<> i Design ~<> i Debug ~<> i NoToolWin

Adding a new named window configuration to this list is easy.  First, arrange your windows exactly as you want them to appear.  Second, type this command at the StudioShell prompt:

> new-item dte:/windowConfigurations -name MyConfig Location: PSDTE::dte:\windowConfigurations Available Operations: d+ < Name ---------- ---- MyConfig

There, now you have a named window configuration.  If you ever want your IDE windows to bounce back to their MyConfig locations, just type this:

>invoke-item dte:/windowConfigurations/MyConfig

The windows will arrange themselves back to the configuration you specified.

Here Comes the Awesome

I use a laptop all the time (except when gaming).  At my home office I like to dock the laptop and make use of two large monitors.  In this mode, I like to have Visual Studio tool windows, like the output window, errors, etc, shoved off to a second monitor.  Unfortunately undocking the laptop when I’m in this configuration wreaks havoc with Visual Studio and sends my windows into a swarm of window soup.

No more.

I defined two window configurations: one named “DockedLaptop” where all of my tool windows are on my second monitor, and one named “UndockedLaptop”, where most of my tool windows are hidden.  Works great on-demand.

On-demand is nice.  Automatic is better.

Since StudioShell is just PowerShell, and since PowerShell gives us access to tons of great administrative widgets, we can arrange our windows in response to system events.  I found a little WMI snippet that watches the registry for dock/undock state changes using WMI, and since I can hook into Visual Studio’s IDE now, putting the two together was simple (the original dock/undock code can be found here):

1 function invoke-DockStateWindowChange() 2 { 3 $state = get-itemproperty 'hklm:/system/currentControlSet/control/idConfigDB/currentDockInfo' -name DockingState; 4 $configName = "UndockedLaptop"; 5 if( 1 -eq $state.DockingState ) 6 { 7 $config = "DockedLaptop"; 8 } 9 10 invoke-item "dte:/windowConfigurations/$config"; 11 } 12 13 register-wmievent -action {invoke-DockStateWindowChange} -query @" 14 Select * from RegistryValueChangeEvent WITHIN 1 WHERE 15 Hive='HKEY_LOCAL_MACHINE' AND 16 KeyPath='SYSTEM\\CurrentControlSet\\Control\\IDConfigDB\\CurrentDockInfo' AND 17 ValueName='DockingState' 18 "@ ;

The code looks a bit messy because of the WMI query, but the logic is quite simple.  The invoke-DockStateWindowChange function checks the registry for a value indicating the docking state of my laptop.  Depending on this value, one of two window configurations is invoked. 

The rest is hooking into WMI to monitor the registry for changes.  When the docking state changes, the registry is updated, the WMI event is raised, my function is called, and my windows arrange themselves the way I want them to be.

Dropped the code into my StudioShell profile script (you can find yours at ~/documents/codeowlsllc.studioshell/profile.ps1), and it just works.  Now whenever I dock or undock, my windows end up where I want them instead of where they happen to land.

Note

I know the WMI registry event trick doesn’t work for some laptop docks – late-model Dells in particular.  As an alternative the code below taps into the power source change events, which isn’t as nice – you can’t tell what power source is being used, but at least you can always fallback your IDE windows to a safe configuration when your docking state changes.

1 function invoke-DockStateWindowChange() 2 { 3 invoke-item "dte:/windowConfigurations/undockedLaptop"; 4 } 5 6 register-wmievent -action {invoke-DockStateWindowChange} -class win32_powermanagementevent

So, how will StudioShell add awesome to your daily development life?