Ответ 1
Да, я написал расширение для исправления этой проблемы в VS10 и VS11: http://visualstudiogallery.msdn.microsoft.com/6705affd-ca37-4445-9693-f3d680c92f38
Enjoy.
Если у меня открыто 10 файлов, и я исправляю свой файл csproj
(например: добавить space), жалуется:
The project "XYZ" has been modified outside the environment. Press Reload to load the updated project from disk. Press Ignore to ignore the external changes. The change will be used the next time you open the project.
Теперь я действительно хочу перезагрузить, потому что есть важные изменения, но я не хочу, чтобы Visual Studio закрывала все мои открытые файлы, вместо этого я хотел бы, чтобы это обновите те, которые все еще существуют и закрывают недостающие.
Есть ли способ получить такую функциональность?
Да, я написал расширение для исправления этой проблемы в VS10 и VS11: http://visualstudiogallery.msdn.microsoft.com/6705affd-ca37-4445-9693-f3d680c92f38
Enjoy.
Поскольку эта функциональность не построена, я написал следующий макрос:
Public Sub ReloadProject()
Dim oldFiles As List(Of String)
oldFiles = New List(Of String)
Dim projName = DTE.ActiveDocument.ProjectItem.ContainingProject.Name
For iDoc = DTE.Documents.Count To 1 Step -1
Dim name = (DTE.Documents.Item(iDoc).FullName)
oldFiles.Add(name)
DTE.Documents.Item(iDoc).Close(vsSaveChanges.vsSaveChangesPrompt)
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()
For Each file In oldFiles
Dim item = DTE.Solution.FindProjectItem(file)
If Not item Is Nothing Then
item.Open()
item.Document.Activate()
End If
Next
End Sub
Когда я получаю раздражающее окно, требующее перезагрузки, я игнорирую его. А затем запустите этот макрос после перезагрузки.
Так как макросы недоступны в Visual Studio 2013, вам нужна надстройка для запуска макросов. Visual Commander (доступно в Галерее), кажется, делает трюк. Я скорректировал макрос Sam Saffron для работы в VS 2013 с помощью Visual Commander.
Изменить февраль 2015: Я также улучшил его, чтобы запомнить номер строки и столбец активного документа и записать любые ошибки в окно вывода макроса Visual Studio.
Последняя версия здесь: https://gist.github.com/nycdotnet/947025d922fa2af87d03
'===============================================================================
' 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 Qaru thread: http://stackoverflow.com/info/3783648/is-there-a-setting-in-vs-2010-that-will-allow-it-to-recover-open-files-after-a-p/28130299#28130299
'===============================================================================
Imports EnvDTE
Imports EnvDTE80
Imports Microsoft.VisualStudio.Shell
Imports VisualCommanderExt
Imports System
Imports System.Collections.Generic
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
WriteOutput("You must have a document open to reload a project with this macro.")
Exit Sub
End If
Dim projName = DTE.ActiveDocument.ProjectItem.ContainingProject.Name
Dim activeDocFullName = DTE.ActiveDocument.FullName
Dim objSel As TextSelection = DTE.ActiveDocument.Selection
Dim objActive As VirtualPoint = objSel.ActivePoint
Dim intOriginallyActiveRowNumber As Integer = objActive.Line
Dim intOriginallyActiveColumnNumber As Integer = objActive.LineCharOffset
For iDoc = DTE.Documents.Count To 1 Step -1
Dim name = (DTE.Documents.Item(iDoc).FullName)
oldFiles.Add(name)
DTE.Documents.Item(iDoc).Close(vsSaveChanges.vsSaveChangesPrompt)
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()
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()
Dim ts as TextSelection = item.Document.Selection
ts.MoveToLineAndOffset(intOriginallyActiveRowNumber,intOriginallyActiveColumnNumber,false)
End If
End If
Next
Catch Ex as Exception
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
End Class