How to add parsing errors to ErrorList window?
I am working on a project to create a language service using Managed Package Framework. I want to show the parser errors in the error list window. Using DTE2, I can get a handle of ErrorList Window.
EnvDTE80.Window2 window = dte2.Windows.Item(EnvDTE80.WindowKinds.vsWindowKindErrorList);
ErrorList myErrorList = CType(window.Object, EnvDTE80.ErrorList);
However myErrorList does not expose Add method on ErrorItems collection. What is the way to add the error items programatically?
Can anyone help?
Thanks in advance.
Vinay Ahuja
Answers
IServiceProvider is passed to every package as it is created. If you are using MPF you can call GetService on the class implementing MSVSIP.Package, or you can call the static method MSVSIP.Package.GetGlobalService from any other class.
Craig
- See:
HOWTO: Add an error with navigation to the Error List from a Visual Studio add-in
http://www.mztools.com/resources_vsnet_addins.aspx
MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com- Marked As Answer byCarlos Quintero - MVPMVP, ModeradorMonday, October 06, 2008 9:00 AM
All Replies
The error list is read only from the automation model. An error item is tightly tied to the compiler or other item producer, more so than a task item. Therefore we decided to make the error list read only from the DTE model. You can create a task provider for the error list in a package.
Craig
Craig,
I found ErrorListProvider and ErrorTask classes in the documentation. What I am not able to figure out is how to get the IServiceProvider interface in language service to create the ErrorListProvider.
Can you point me where can I find more details or if there is an example to do this?
Thanks,
Vinay- Proposed As Answer bySerge van den Oever - Macaw Friday, October 03, 2008 9:38 PM
IServiceProvider is passed to every package as it is created. If you are using MPF you can call GetService on the class implementing MSVSIP.Package, or you can call the static method MSVSIP.Package.GetGlobalService from any other class.
Craig
I am having trouble implementing this. I'm using GetGlobalService to get the IServiceProvider and using this in the ErrorListProvider constructor. I'm creating a new ErrorTask item and trying to add it using the Tasks.Add method of my ErrorListProvider instance, but I keep getting this error:
The service "Microsoft.VisualStudio.Shell.Interop.IVsTaskList" must be installed for this feature to work"
Thanks,
Mike
I am also having the same error message. Anyone out there with an idea why this message is shown?- I use the following code to create an error list provider:
if (_errorListProvider == null) { IServiceProvider serviceProvider = new ServiceProvider(VsPackage.ApplicationObject as Microsoft.VisualStudio.OLE.Interop.IServiceProvider); _errorListProvider = new ErrorListProvider(serviceProvider); _errorListProvider.ProviderName = "Factory Guide Errors"; _errorListProvider.ProviderGuid = new Guid("5A10E43F-8D1D-4026-98C0-E6B502058901"); }
Note that you need to keep the erorr list provider alive, all your erorrs are connected to the provider, also use the same error list provider to report all your errors to.
Reporting the error can be done as follows:
/// <summary> /// Write an entry to the Visual Studio Error List. /// </summary> /// <param name="category">Category: Error or Warning</param> /// <param name="text">The text of the error or warning</param> /// <param name="code">The code of the error or warning</param> /// <param name="path">The path to the file containing the error</param> /// <param name="line">The line in the file where the error occured</param> /// <param name="column">The column in the file where the error occured</param> /// <returns>The error or warning output string</returns> public static string WriteVisualStudioErrorList(MessageCategory category, string text, string code, string path, int line, int column) { if (_errorListProvider == null) { IServiceProvider serviceProvider = new ServiceProvider(VsPackage.ApplicationObject as Microsoft.VisualStudio.OLE.Interop.IServiceProvider); _errorListProvider = new ErrorListProvider(serviceProvider); _errorListProvider.ProviderName = "Factory Guide Errors"; _errorListProvider.ProviderGuid = new Guid("5A10E43F-8D1D-4026-98C0-E6B502058901"); // _errorListProvider.ForceShowErrors(); } string textline = null; // Determine the task priority TaskPriority priority = category == MessageCategory.Error ? TaskPriority.High : TaskPriority.Normal; TaskErrorCategory errorCategory = category == MessageCategory.Error ? TaskErrorCategory.Error : TaskErrorCategory.Warning; switch (errorCategory) { case TaskErrorCategory.Error: _errors++; break; case TaskErrorCategory.Warning: _warnings++; break; } // Check if this error is already in the error list, don't report more than once bool alreadyReported = false; foreach (ErrorTask task in _errorListProvider.Tasks) { if (task.ErrorCategory == errorCategory && task.Document == path && task.Line == line - 1 && task.Column == column - 1 && task.Text == text) { alreadyReported = true; break; } } if (!alreadyReported) { // Add error to task list ErrorTask task = new ErrorTask(); task.Document = path; task.Line = line - 1; // The task list does +1 before showing this number. task.Column = column - 1; // The task list does +1 before showing this number. task.Text = text; task.Priority = priority; // High or Normal task.ErrorCategory = errorCategory; // Error or Warning, no support for Message yet task.Category = TaskCategory.BuildCompile; // task.HierarchyItem = hierarchy; task.Navigate += new EventHandler(NavigateTo); if (VisualStudioExtensions.ContainsLink(text)) { task.Help += new EventHandler(task_Help); } _errorListProvider.Tasks.Add(task); switch (errorCategory) { case TaskErrorCategory.Error: _uniqueErrors++; break; case TaskErrorCategory.Warning: _uniqueWarnings++; break; } string categoryString = category == MessageCategory.Error ? "error" : "warning"; textline = MessageGeneration.Generate(category, text, code, path, line, column); } return textline; } /// <summary> /// Navigate to the file, line and column reported in the task /// </summary> /// <param name="sender">The Task to navigate to</param> /// <param name="arguments"></param> private static void NavigateTo(object sender, EventArgs arguments) { Microsoft.VisualStudio.Shell.Task task = sender as Microsoft.VisualStudio.Shell.Task; if (task == null) { throw new ArgumentException("sender"); } // If the name of the file connected to the task is empty there is nowhere to navigate to if (String.IsNullOrEmpty(task.Document)) { return; } IServiceProvider serviceProvider = new ServiceProvider(VsPackage.ApplicationObject as Microsoft.VisualStudio.OLE.Interop.IServiceProvider); IVsUIShellOpenDocument openDoc = serviceProvider.GetService(typeof(IVsUIShellOpenDocument)) as IVsUIShellOpenDocument; if (openDoc == null) { return; } IVsWindowFrame frame; Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp; IVsUIHierarchy hier; uint itemid; Guid logicalView = VSConstants.LOGVIEWID_Code; if (ErrorHandler.Failed(openDoc.OpenDocumentViaProject( task.Document, ref logicalView, out sp, out hier, out itemid, out frame)) || frame == null ) { return; } object docData; frame.GetProperty((int)__VSFPROPID.VSFPROPID_DocData, out docData); // Get the VsTextBuffer VsTextBuffer buffer = docData as VsTextBuffer; if (buffer == null) { IVsTextBufferProvider bufferProvider = docData as IVsTextBufferProvider; if (bufferProvider != null) { IVsTextLines lines; ErrorHandler.ThrowOnFailure(bufferProvider.GetTextBuffer(out lines)); buffer = lines as VsTextBuffer; Debug.Assert(buffer != null, "IVsTextLines does not implement IVsTextBuffer"); if (buffer == null) { return; } } } // Finally, perform the navigation. IVsTextManager mgr = serviceProvider.GetService(typeof(VsTextManagerClass)) as IVsTextManager; if (mgr == null) { return; } mgr.NavigateToLineAndColumn(buffer, ref logicalView, task.Line, task.Column, task.Line, task.Column); } /// <summary> /// Determines whether the task text contains a url, we assume that url is help. /// </summary> /// <param name="text">The task text.</param> /// <returns> /// <c>true</c> if the text contains a link, assume its a help link; otherwise, <c>false</c>. /// </returns> static bool ContainsLink(string text) { if (text == null) { throw new ArgumentNullException("text"); } Match urlMatches = Regex.Match(text, @"((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)"); return urlMatches.Success; } /// <summary> /// Handles the Help event of the task control. /// </summary> /// <param name="sender">The Task to parse for a guidance link.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> static void task_Help(object sender, EventArgs e) { Microsoft.VisualStudio.Shell.Task task = sender as Microsoft.VisualStudio.Shell.Task; if (task == null) { throw new ArgumentException("sender"); } string url = null; Match urlMatches = Regex.Match(task.Text, @"((https?|ftp|gopher|telnet|file|notes|ms-help):((//)|(\\\\))+[\w\d:#@%/;$()~_?\+-=\\\.&]*)"); if (urlMatches.Success) { url = urlMatches.Captures[0].Value; } if (url != null) { VsPackage.ApplicationObject.ItemOperations.Navigate(url, vsNavigateOptions.vsNavigateOptionsDefault); } }
The MessageCategory enum is my own simple enum.
It did cost a lot of time to get to this code, seems to work. Not much info avaiilable.
By the way, I'm using the following references:
using System; using System.Collections.Generic; using System.Diagnostics; using System.Text.RegularExpressions; using EnvDTE; using Macaw.FactoryIdeTools.DotNet2.Framework.Business.Components; // my own stuff, defines MessageCategory using Microsoft.VisualStudio; using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.Shell.Interop; using Microsoft.VisualStudio.TextManager.Interop; - See:
HOWTO: Add an error with navigation to the Error List from a Visual Studio add-in
http://www.mztools.com/resources_vsnet_addins.aspx
MZ-Tools: Productivity add-ins for Visual Studio: http://www.mztools.com- Marked As Answer byCarlos Quintero - MVPMVP, ModeradorMonday, October 06, 2008 9:00 AM


