|
'=============================================================================== |
|
' 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 |