I have been vexed for some time now by an issue with Visual Studio window layouts.  Like many people, I use multiple monitors at work.  When working in Visual Studio I prefer to undock all my tool and output windows and group them in my second monitor.  This leaves my primary monitor free for as much code on one screen as possible.

PROBLEM:

When I use my workstation via Remote Desktop, Visual Studio munges all the window positions in a failed attempt to squeeze my multi-monitor settings onto one screen.  If you haven’t seen this, you can take my word for it that it is not pretty.  What’s worse, the settings don’t revert to normal when logging back in directly.

SOLUTION:

After trawling through the VS IDE documentation I came up with a solution that uses two VS settings files to store different window layouts.  First, I exported a window layout settings file for one monitor and another window layout settings file for two monitors (I wish I’d found that link before searching all the relevant documentation myself!).

Rather than explicitly switch from one layout to another, I want Visual Studio to automatically use the correct monitor setup when I start the IDE.  With this in mind, I pointed the Visual Studio “Team Settings” option to a well-known location for a settings override file of my own.

Tools/Options Dialog

I created a script that runs every time I start Visual Studio (you could point your VS shortcuts to such a script and start VS at the end, if you like).  This script simply checks the number of screens to determine which window layout to use.

The first version of the script actually copied files around but after some scrutiny with Process Monitor I found that I could simply twiddle one registry entry to point Visual Studio at the right settings file (this is actually the *second* registry change in the script below).

001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
031
032
033
034
035
[system.reflection.assembly]::LoadWithPartialName('system.windows.forms')

if ([System.Windows.Forms.Screen]::AllScreens.Count -gt 1)
{
    $newSettingsFileName = "TwoMonitorLayout.vssettings"
   
    # HACK to restore which monitor VS opens into
    # "These magic numbers work on my machine!" ;-)
    Set-ItemProperty HKCU:\Software\Microsoft\VisualStudio\9.0 MainWindow "-934 60 823 880 3"
}
else
{
    $newSettingsFileName = "OneMonitorLayout.vssettings"
}   

$settings = Join-Path $Env:FZ_USER_ROOT $newSettingsFileName

if (Test-Path $settings)
{
    Set-ItemProperty HKCU:\Software\Microsoft\VisualStudio\9.0\Profile TeamSettingsFile $settings

    # Visual Studio will only use the team settings file if it is newer
    # FYI: Source control sets checked-in files to be ReadOnly

    $settingsFile = Get-Item $settings

    $settingsFile.Set_IsReadOnly($false)
    $settingsFile.LastWriteTime = [DateTime]::Now
    $settingsFile.Set_IsReadOnly($true)
}
else
{
    Write-Output "WARNING: Failed to find a Visual Studio settings file at $settings"
}

You may have noticed that I have some hard coded numbers in that first registry change.  The truth is that when I was testing this I found that Visual Studio always wanted to open in the wrong window after running under Remote Desktop.  This is probably fixable if I were to change which monitor I have set as the primary but I would rather just stuff some known good values into one more registry setting and be done.

By the way, I am new to PowerShell so if you have any tips that would improve this script, please let me know.