Introduction
Although the Visual Studio IDE is a convenient way to develop applications, sometimes a better way to do builds is on the command line. This can often be easier and faster. However, if there are errors (or warnings), it would be nice to be able to fix these using the IDE. There didn't appear to be any way to load the build log files into Visual Studio, so I decided to write a macro to do this. I decided that this should either be invoked from the Tools menu, or by right clicking in the build window. This would ask for a file, which would be loaded into the build window. It would then be possible to view the source code associated with the error, either by double clicking it or by pressing F8, in exactly the same way as if the solution/project had been built within the IDE.
The Code
The code consists of a method which asks the user for a file to load, and reads the file line by line. Each line is then written to the output window as it is read. I decided to write a class for the output window. The constructor to this class takes a name, which in this case will be "build", but we could use names like "debug" or even specify a new name to create a new pane in the output window. The only service I have written in this class is Writeline
which writes a line of text and then follows it with CR/LF. Other actions are achieved by accessing the Pane
property, and calling services on this object.
Public Class NamedOutputPane
Private win As OutputWindowPane
Public ReadOnly Property Pane() As OutputWindowPane
Get
Return win
End Get
End Property
Sub New(ByRef WindowName As String)
win = Nothing
Dim DTE As EnvDTE.DTE
DTE = System.Runtime.InteropServices.Marshal. _
GetActiveObject("VisualStudio.DTE")
Dim mwin As Window = DTE.Windows.Item(EnvDTE.Constants _
.vsWindowKindOutput)
Dim OW As OutputWindow = mwin.Object
Dim tmpOWp As OutputWindowPane
For Each tmpOWp In OW.OutputWindowPanes
If tmpOWp.Name = WindowName Then
win = tmpOWp
Exit For
End If
Next
If win Is Nothing Then
win = OW.OutputWindowPanes.Add(WindowName)
End If
End Sub
Sub OutputTextLine(ByRef txt As String)
win.OutputString(txt)
win.OutputString(vbCr)
End Sub
End Class
The other method that I needed, that I wrote as a stand alone function, was to bring up a file open dialog, and ask for the name of the log file to read. This returns the name selected or Nothing
if cancel was pressed. This uses the class WinWrapper
in order to find the parent window. If you don't do this, the dialog won't always get the focus, and may be hidden behind the main window. I found this code in the sample macros.
Function AskForFileName() As String
Dim winptr As WinWrapper = New WinWrapper
Try
Dim openfile As Forms.FileDialog = New Forms.OpenFileDialog
If openfile.ShowDialog(winptr) = Forms.DialogResult.OK Then
AskForFileName = openfile.FileName
End If
Catch err As System.Exception
MsgBox(err.Message)
End Try
End Function
And then finally the main method. Having done all the groundwork, all that needs to be done is to call the getname
function and read the file line by line. Each line is written to the output window as it is read.
Sub ReadLogFile()
Dim FileName As String = AskForFileName()
If Not FileName Is Nothing Then
Dim OutWin As NamedOutputPane = New NamedOutputPane("Build")
OutWin.Pane().Activate() OutWin.Pane().Clear()
Dim sr As StreamReader = New StreamReader(FileName)
Try
Dim line As String
Do
line = sr.ReadLine()
OutWin.OutputTextLine(line)
Loop Until line Is Nothing
sr.Close()
Catch E As Exception
OutWin.Pane().OutputString("The file could not be read:")
OutWin.OutputTextLine(E.Message)
End Try
End If
End Sub
And that's it! All that remained was to add it to the Tools menu and the context (right mouse) menu. I did this by making it an add-in. The Tools menu option I did by selecting the right option in the wizard, and the right mouse menu is done using the following code:
CommandObj = applicationObject.Commands.AddNamedCommand(objAddIn, _
"ReadLogFile", _
"Read Log File", _
"Read log from file into build window", _
False, 101, Nothing, 1 + 2)
CommandObj.AddControl(applicationObject.CommandBars.Item("Tools"))
CommandObj.AddControl(applicationObject.CommandBars. _
Item("Output Window Pane"))
The errors and warnings behave just as if the code had been built within the IDE, so the code can be viewed by double clicking on the error, pressing F8 etc.
History
- 01 Jan 2004 - Initial version.