![]() |
||||
Visual Studio 2005 (and higher) provides an Error List window ("View", "Error List" menu) to show
errors from compilers, etc. Errors can be truly Errors, Warnings or Messages.
However, the OutputTaskItemString doesn't show the project of in Project column and doesn't provide navigation to the document when double-clicking an item in the list. This article shows an alternate approach to overcome these limitations. More Information The automation model (EnvDTE80) of Visual Studio provides the EnvDTE80.ErrorList class to represent the Error List. You can get an instance of this class as explained in the following article: HOWTO: Get the programmable inner object of a toolwindow To get more information about the EnvDTE80.dll assembly, see the following article: INFO: Assemblies used in Visual Studio Extensibility The ErrorItems property provides the collection of errors, but not the Add The ErrorItems property provides the collection of errors, but it lacks an Add method and the OutputWindowPane.OutputTaskItemString method has some limitations. Supposedly only Visual Studio packages can fully contribute to the error list implementing an ErrorListProvider. The Microsoft.VisualStudio.Shell.dll assembly provides an ErrorListProvider implementation that will be used from an add-in to add errors to the Error List. The project sample needs references to the following assemblies:
To know how to add these assemblies as references to a project, see the following article: HOWTO: Reference a Visual Studio assembly in the GAC from an add-in The following add-in adds when loaded three errors (an error, warning and message) to the Error List associated to the first three lines of the first file of the first project of the solution (ensure that there is a solution loaded when loading the add-in). Notice that errors should be removed from the list when their project is removed from the solution, or when the solution is unloaded. It also shows how to navigate to the line of the file when the error is double-clicked.
Imports SystemvDTE
Imports EnvDTE80
Imports System.Windows.Forms
Imports Microsoft.VisualStudio.Shell
Imports System.Runtime.InteropServices
Imports Microsoft.VisualStudio
Imports Microsoft.VisualStudio.Shell.Interop
Imports System.Collections.Generic
Public Class Connect
Implements IDTExtensibility2
Implements System.IServiceProvider
Private m_objDTE As DTE
Private m_objErrorListProvider As ErrorListProvider
Private m_colErrorTasks As List(Of ErrorTask)
Private WithEvents m_objSolutionEvents As SolutionEvents
Public Sub OnConnection(ByVal application As Object, ByVal connectMode As ext_ConnectMode, _
ByVal addInInst As Object, ByRef custom As Array) Implements IDTExtensibility2.OnConnection
m_objDTE = CType(application, DTE)
Select Case connectMode
Case ext_ConnectMode.ext_cm_AfterStartup
OnStartupComplete(Nothing)
Case ext_ConnectMode.ext_cm_Startup
' OnStartupComplete will be called automatically
End Select
End Sub
Public Sub OnDisconnection(ByVal disconnectMode As ext_DisconnectMode, ByRef custom As Array) _
Implements IDTExtensibility2.OnDisconnection
RemoveTasks()
End Sub
Public Sub OnAddInsUpdate(ByRef custom As Array) Implements IDTExtensibility2.OnAddInsUpdate
End Sub
Public Sub OnBeginShutdown(ByRef custom As Array) Implements IDTExtensibility2.OnBeginShutdown
End Sub
Public Sub OnStartupComplete(ByRef custom As Array) Implements IDTExtensibility2.OnStartupComplete
Try
m_objSolutionEvents = m_objDTE.Events.SolutionEvents
InitializeErrorListProvider()
AddSampleErrors()
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub InitializeErrorListProvider()
m_colErrorTasks = New List(Of ErrorTask)
m_objErrorListProvider = New Microsoft.VisualStudio.Shell.ErrorListProvider(Me)
m_objErrorListProvider.ProviderName = "My Error Provider"
' TODO: (IMPORTANT) Use your OWN Guid here:
m_objErrorListProvider.ProviderGuid = New Guid("5BA8BB0D-D517-45ae-966C-864C536454F1")
m_objErrorListProvider.Show()
End Sub
Private Sub AddSampleErrors()
Dim objProject As Project
Dim objProjectItem As ProjectItem
If Not m_objDTE.Solution.IsOpen Then
MessageBox.Show("Open or create a solution.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
If m_objDTE.Solution.Projects.Count = 0 Then
MessageBox.Show("Open or create a solution with at least one project.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
objProject = m_objDTE.Solution.Projects.Item(1)
If objProject.ProjectItems.Count = 0 Then
MessageBox.Show("Open or create a project with at least one file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
objProjectItem = objProject.ProjectItems.Item(1)
AddErrorToErrorList(objProject, objProjectItem, "My custom error", TaskErrorCategory.Error, 1, 1)
AddErrorToErrorList(objProject, objProjectItem, "My custom warning", TaskErrorCategory.Warning, 2, 1)
AddErrorToErrorList(objProject, objProjectItem, "My custom message", TaskErrorCategory.Message, 3, 1)
End If
End If
End If
End Sub
Private Sub AddErrorToErrorList(ByVal objProject As Project, ByVal objProjectItem As ProjectItem, _
ByVal sErrorText As String, ByVal eTaskErrorCategory As TaskErrorCategory, ByVal iLine As Integer, _
ByVal iColumn As Integer)
Dim objErrorTask As ErrorTask
Dim objIVsSolution As Microsoft.VisualStudio.Shell.Interop.IVsSolution
Dim objVsHierarchy As IVsHierarchy = Nothing
Try
objIVsSolution = DirectCast(GetService(GetType(IVsSolution)), IVsSolution)
ErrorHandler.ThrowOnFailure(objIVsSolution.GetProjectOfUniqueName(objProject.UniqueName, objVsHierarchy))
objErrorTask = New Microsoft.VisualStudio.Shell.ErrorTask
objErrorTask.ErrorCategory = eTaskErrorCategory
objErrorTask.HierarchyItem = objVsHierarchy
objErrorTask.Document = objProjectItem.FileNames(0)
' VS uses indexes starting at 0 while the automation model uses indexes starting at 1
objErrorTask.Line = iLine - 1
objErrorTask.Column = iColumn
objErrorTask.Text = sErrorText
AddHandler objErrorTask.Navigate, AddressOf ErrorTaskNavigate
m_colErrorTasks.Add(objErrorTask)
m_objErrorListProvider.Tasks.Add(objErrorTask)
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub ErrorTaskNavigate(ByVal sender As Object, ByVal e As EventArgs)
Dim objErrorTask As ErrorTask
Dim bResult As Boolean
Try
objErrorTask = CType(sender, ErrorTask)
objErrorTask.Line += 1 ' Fix the index start
bResult = m_objErrorListProvider.Navigate(objErrorTask, New Guid(EnvDTE.Constants.vsViewKindCode))
objErrorTask.Line -= 1 ' Restore the index start
If Not bResult Then
MessageBox.Show("Error navigating to " & objErrorTask.Text, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Function GetService(ByVal serviceType As System.Type) As Object _
Implements System.IServiceProvider.GetService
Dim objService As Object = Nothing
Try
objService = Microsoft.VisualStudio.Shell.Package.GetGlobalService(serviceType)
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
Return objService
End Function
Private Sub m_objSolutionEvents_BeforeClosing() Handles m_objSolutionEvents.BeforeClosing
RemoveTasks()
End Sub
Private Sub m_objSolutionEvents_ProjectRemoved(ByVal objProject As EnvDTE.Project) _
Handles m_objSolutionEvents.ProjectRemoved
Dim objErrorTask As ErrorTask
Dim objErrorTaskProject As Project
Dim objObject As Object = Nothing
Try
If Not (m_colErrorTasks Is Nothing) Then
For iCounter As Integer = m_colErrorTasks.Count - 1 To 0 Step -1
objErrorTask = m_colErrorTasks.Item(iCounter)
ErrorHandler.ThrowOnFailure(objErrorTask.HierarchyItem.GetProperty( _
VSConstants.VSITEMID_ROOT, __VSHPROPID.VSHPROPID_ExtObject, objObject))
If TypeOf objObject Is Project Then
objErrorTaskProject = DirectCast(objObject, Project)
If objErrorTaskProject.UniqueName = objProject.UniqueName Then
RemoveTask(objErrorTask)
End If
End If
Next
End If
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub RemoveTasks()
Dim objErrorTask As ErrorTask
Try
If Not (m_colErrorTasks Is Nothing) Then
For iCounter As Integer = m_colErrorTasks.Count - 1 To 0 Step -1
objErrorTask = m_colErrorTasks.Item(iCounter)
RemoveTask(objErrorTask)
Next
End If
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Private Sub RemoveTask(ByVal objErrorTask As ErrorTask)
Try
m_objErrorListProvider.SuspendRefresh()
RemoveHandler objErrorTask.Navigate, AddressOf ErrorTaskNavigate
m_colErrorTasks.Remove(objErrorTask)
m_objErrorListProvider.Tasks.Remove(objErrorTask)
Catch objException As Exception
MessageBox.Show(objException.ToString, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
Finally
m_objErrorListProvider.ResumeRefresh()
End Try
End Sub
End Class
Related articles Go back to the 'Resources for Visual Studio .NET extensibility' section for more articles like this
|
| Copyright © 2000-2013 MZTools Software. All Rights Reserved. Legal Notice |