5

How do I backup window layouts in Visual Studio 2015/2017?

Exporting settings does not export all layouts (just current one). I know there is a directory under AppData/Roaming/Microsoft/VisualStudio called WindowLayouts but that again stores only current layout.

I want to backup all of them without exporting settings for each layout.
Where does Visual Studio store them?

Snostorp
  • 135
UfoXp
  • 211

1 Answers1

2

Visual Studio 2017+ saved the window layout information for side-by-side installations under [LOCALAPPDATA]/Microsoft/VisualStudio/{VisualStudioInstanceID}.

I wrote a script which loops through all instances, via vswhere.exe, and backup and restore (ping me if interests!) these settings.

Note: Please make sure you have vswhere.exe downloaded and available in your current PATH environment variable when executing the script.

Backup

backup-windowlayoutinfolist.ps1:

#!/usr/bin/env pwsh

[CmdletBinding()]
param()

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

# Import modules
try { Import-Module SmartLogging } catch { Install-Module SmartLogging -Scope CurrentUser -Force; Import-Module SmartLogging }
try { Import-Module Execution } catch { Install-Module Execution -Scope CurrentUser -Force; Import-Module Execution }

Set-ScriptArgs $MyInvocation.BoundParameters $MyInvocation.UnboundArguments

function Backup-VisualStudioWindowLayouts([string] $vsLocalAppDataDir, [string] $versionAndInsanceId) {
    Log trace "vsLocalAppDataDir: $vsLocalAppDataDir"
    Log trace "versionAndInsanceId: $versionAndInsanceId"

    $sourceFilePath = Join-Path $vsLocalAppDataDir 'ApplicationPrivateSettings.xml'
    $destinationDir = Join-Path $PSScriptRoot "config/$versionAndInsanceId"
    $destinationFilePath = Join-Path $destinationDir 'WindowLayoutInfoList.xml'

    if (-not (Test-Path $destinationDir -PathType Container) ) {
        New-Item -Path $destinationDir -ItemType Directory > $null
    }

    [xml]$xml = Get-Content -Path $SourceFilePath

    $windowLayoutInfoListXml = $xml.SelectSingleNode($XpathSearchPattern)

    $windowLayoutInfoListXml.OuterXml | Set-Content -Path $DestinationFilePath -Force
    Log info "Saved window layout to '$DestinationFilePath'"
}

try {
    $XpathSearchPattern = "/content/indexed/collection[@name='Microsoft.VisualStudio.Platform.WindowManagement.Layouts.WindowLayoutInfoList']"

    $Instances = Start-NativeExecution vswhere.exe -prerelease -products * -legacy -format json | ConvertFrom-Json
    foreach ($instance in $Instances) {
        if (-not ('installationName' -in $instance.PSObject.Properties.Name)) {
            $instance | Add-Member -NotePropertyName 'installationName' -NotePropertyValue 'n/a'
        }

        $buildVersion = [Version]::new($instance.installationVersion)
        $versionAndInsanceId = "$($buildVersion.Major).0_$($instance.instanceId)"
        $vsLocalAppDataDir = Join-Path $env:LOCALAPPDATA (Join-Path 'Microsoft/VisualStudio' $versionAndInsanceId)
        if (Test-Path $vsLocalAppDataDir) {
            Log info "Backup window layouts for Visual Studio Version $($instance.installationVersion) ($($instance.installationName))..."
            Backup-VisualStudioWindowLayouts -vsLocalAppDataDir $vsLocalAppDataDir -versionAndInsanceId $versionAndInsanceId
            Log info "Backup window layouts for Visual Studio Version $($instance.installationVersion) ($($instance.installationName))... Done."
        }
    }

    Log info 'Successfully'
    Exit-WithAndWaitOnExplorer 0
} catch {
    Log error "Something went wrong: $_"
    Log trace "Exception: $($_.Exception)"
    Log trace "StackTrace: $($_.ScriptStackTrace)"
    Exit-WithAndWaitOnExplorer 1
}
Manuel
  • 21