Skip to content

Instantly share code, notes, and snippets.

@nycdotnet
Last active August 29, 2015 14:15
Show Gist options
  • Save nycdotnet/947025d922fa2af87d03 to your computer and use it in GitHub Desktop.
Save nycdotnet/947025d922fa2af87d03 to your computer and use it in GitHub Desktop.
Visual Studio Project Reload Macro

Use this macro in Visual Studio 2013 with the Visual Commander extension.

Original Stack Overflow thread: http://stackoverflow.com/questions/3783648/is-there-a-setting-in-vs-2010-that-will-allow-it-to-recover-open-files-after-a-p/28130299#28130299

The macro unloads and reloads the project of the currently active document. If there is no active document, a warning is emitted to the Visual Studio output window. The macro also remembers the current cursor position of all documents, so less time is lost in this operation.

'===============================================================================
' This macro originally written by Sam Saffron, adapted for Visual Studio 2013
' by Steve Ognibene. Run in Visual Studio with a macro launcher such as the
' Visual Commander extension.
' Latest version will be here: https://gist.github.com/nycdotnet/947025d922fa2af87d03
' Original Stack Overflow thread: http://stackoverflow.com/questions/3783648/is-there-a-setting-in-vs-2010-that-will-allow-it-to-recover-open-files-after-a-p/28130299#28130299
' Also, thanks to Jeremy Jameson for code to write to VS Output window in a macro:
' http://blogs.msdn.com/b/jjameson/archive/2009/03/11/tracing-and-logging-from-visual-studio-macros.aspx
'===============================================================================
Option Explicit On
Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualStudio.Shell
Imports VisualCommanderExt
Imports System
Imports System.Collections.Generic
Imports System.Windows.Forms
Public Class C
Implements ICommand
Private DTE As DTE2
Sub Run(InboundDTE As DTE2, package As Package) Implements ICommand.Run
Me.DTE = InboundDTE
ReloadProject(DTE)
End Sub
Public Sub ReloadProject(DTE As DTE2)
Try
Dim oldFiles As New List(Of String)
Dim iDoc As Object
If DTE.ActiveDocument Is Nothing Then
MessageBox.Show("You must have a document open to reload a project with this macro.")
Exit Sub
End If
Dim objOpenFilesDictionary As New Dictionary(Of String, VSOpenFileInfo)
Dim projName = DTE.ActiveDocument.ProjectItem.ContainingProject.Name
Dim activeDocFullName = DTE.ActiveDocument.FullName
For iDoc = DTE.Documents.Count To 1 Step -1
With DTE.Documents.Item(iDoc)
Dim name = .FullName
oldFiles.Add(name)
Dim point As VirtualPoint = .Selection.ActivePoint
objOpenFilesDictionary.Add(name, New VSOpenFileInfo(name, point.Line, point.LineCharOffset))
.Close(vsSaveChanges.vsSaveChangesPrompt)
End With
Next
Dim projPath As String = DTE.Solution.Properties.Item("Name").Value.ToString() & "\" & projName
Dim solutionExplorer As Window = DTE.Windows.Item(Constants.vsWindowKindSolutionExplorer)
solutionExplorer.Activate()
Dim solutionHierarchy As UIHierarchy = solutionExplorer.Object
Dim obj As Object = solutionHierarchy.GetItem(projPath)
obj.Select(vsUISelectionType.vsUISelectionTypeSelect)
DTE.ExecuteCommand("Project.UnloadProject")
DTE.ExecuteCommand("Project.ReloadProject")
oldFiles.Reverse()
're-open all previously open files
For Each file As Object In oldFiles
Dim item = DTE.Solution.FindProjectItem(file)
If Not item Is Nothing Then
item.Open()
item.Document.Activate()
If (Not String.IsNullOrEmpty(item.Document.FullName)) AndAlso objOpenFilesDictionary.ContainsKey(item.Document.FullName) Then
'restore previous file position
Dim info = objOpenFilesDictionary(item.Document.FullName)
Dim ts As TextSelection = item.Document.Selection
If info.IsValid() And (Not ts Is Nothing) Then
ts.MoveToLineAndOffset(info.CursorRow, info.CursorColumn, False)
End If
End If
End If
Next
'reactivate previously active file
For Each file As Object In oldFiles
If file = activeDocFullName Then
Dim item = DTE.Solution.FindProjectItem(file)
If Not item Is Nothing Then
item.Document.Activate()
Exit For
End If
End If
Next
Catch Ex As Exception
MessageBox.Show("Quick Reload Exception: " & ex.Message & System.Environment.NewLine & "Open 'Macros' Output window for stack trace.")
WriteOutput("Exception: " & ex.Message & System.Environment.NewLine & ex.StackTrace)
End Try
End Sub
Private Function GetMacroOutputPane() As OutputWindowPane
Dim ow As OutputWindow = _
DTE.Windows.Item(Constants.vsWindowKindOutput).Object()
Dim outputPane As OutputWindowPane
Try
outputPane = ow.OutputWindowPanes.Item("Macros")
Catch ex As Exception
outputPane = ow.OutputWindowPanes.Add("Macros")
End Try
Return outputPane
End Function
Private Sub WriteOutput(ByVal s As String)
Dim buffer = New System.Text.StringBuilder
buffer.Append(Date.Now.ToLongTimeString())
buffer.Append(" ")
buffer.Append(s)
buffer.Append(System.Environment.NewLine)
Dim output As String = buffer.ToString()
Dim outputPane As OutputWindowPane = GetMacroOutputPane()
outputPane.OutputString(output)
End Sub
Private Class VSOpenFileInfo
Public FullFileName As String
Public CursorRow As Integer
Public CursorColumn As Integer
Public Sub New(FullFileName As String, Optional CursorRow As Integer = 1, Optional CursorColumn As Integer = 1)
Me.FullFileName = FullFileName
Me.CursorRow = CursorRow
Me.CursorColumn = CursorColumn
End Sub
Public Function IsValid() As Boolean
Return (Not String.IsNullOrEmpty(FullFileName)) And _
CursorRow > 0 And _
CursorColumn > 0
End Function
End Class
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment