Search code examples
c#asynchronousvsixservice-providererror-list

In C#, what and how to pass IServiceProvider in ErrorListProvider(IServiceProvider isp)?


I am creating a vsix project where I need to add some custom errors in Error List window. Now I am stuck in IServiceProvider. What it contains and why I need this and how I can get this? In my code, I need to initialize with a service provider. How can I do this? Following is code :

internal class ErrorListManager
{
    public static ErrorListProvider errorListProvider;

    public static void Initialize(IServiceProvider serviceProvider) 
    {
        errorListProvider = new ErrorListProvider(serviceProvider);

    }

    public static void AddError(string errorMsg) {
        AddTask(errorMsg, TaskErrorCategory.Error);
    }

    private static void AddTask(string errorMsg, TaskErrorCategory category)
    {
        errorListProvider.Tasks.Add(new ErrorTask
        {
            Category = TaskCategory.User,
            ErrorCategory = category,
            Text = errorMsg
        });
    }
}

Please help. I am a beginner for C# and VSIX. Thanks!


Solution

  • To write something in VS Error List you need to use ErrorListProvider. In my implementation, I inherit from ErrorListProvider and implement my own behavior for "ErrorWindowController". The code looks like this (read the code comments for more information):

    public class ErrorWindowController : ErrorListProvider
    {
    
    #region Constructor
    
    /// <summary>
    /// Instance Constructor
    /// </summary>
    /// <param name="aServiceProvider"></param>
    public ErrorWindowController(IServiceProvider aIServiceProvider) : base(aIServiceProvider)
    {
    }
    
    #endregion
    
    
    #region Public Methods
    
    // Use this to add a collection of custom errors in VS Error List
    public void AddErrors(IEnumerable<ErrorModel> aErrors)
    {
        SuspendRefresh();
    
        foreach (ErrorModel error in aErrors)
        {
          ErrorTask errorTask = new ErrorTask
          {
            ErrorCategory = error.Category,
            Document = error.FilePath,
            Text = error.Description,
            Line = error.Line - 1,
            Column = error.Column,
            Category = TaskCategory.BuildCompile,
            Priority = TaskPriority.High,
            HierarchyItem = error.HierarchyItem
          };
          errorTask.Navigate += ErrorTaskNavigate;
          Tasks.Add(errorTask);
        }
    
        BringToFront();
        ResumeRefresh();
    }
    
    // Remove all the errors from Error List which are depending of a project and this specific project is closed
    // Or remove all the errors from Error List when the VS solution is closed
    public void RemoveErrors(IVsHierarchy aHierarchy)
    {
        SuspendRefresh();
    
        for (int i = Tasks.Count - 1; i >= 0; --i)
        {
          var errorTask = Tasks[i] as ErrorTask;
          aHierarchy.GetCanonicalName(Microsoft.VisualStudio.VSConstants.VSITEMID_ROOT, out string nameInHierarchy);
          errorTask.HierarchyItem.GetCanonicalName(Microsoft.VisualStudio.VSConstants.VSITEMID_ROOT, out string nameErrorTaskHierarchy);
          if (nameInHierarchy == nameErrorTaskHierarchy)
          {
            errorTask.Navigate -= ErrorTaskNavigate;
            Tasks.Remove(errorTask);
          }
        }
    
        ResumeRefresh();
    }
    
    // Remove all the errors from the Error List
    public void Clear()
    {
        Tasks.Clear();
    }
    
    
    #endregion
    
    
    #region Private Methods
    
    // This is optional
    // Add navigation for your errors. 
    private void ErrorTaskNavigate(object sender, EventArgs e)
    {
      ErrorTask objErrorTask = (ErrorTask)sender;
      objErrorTask.Line += 1;
      bool bResult = Navigate(objErrorTask, new Guid(EnvDTE.Constants.vsViewKindCode));
      objErrorTask.Line -= 1;
    }
    
    
    #endregion
    }
    

    The ErrorModel is very simple:

    public class ErrorModel
    {
      #region Properties
    
      public string FilePath { get; set; }
    
      public int Line { get; set; }
    
      public int Column { get; set; }
    
      public TaskErrorCategory Category { get; set; }
    
      public string Description { get; set; }
    
      public IVsHierarchy HierarchyItem { get; set; }
    
      #endregion
    
    }
    

    Happy Codding!