Search code examples
.netvb.netvisual-studiovsix

Find specific patterns in project via VS extension


I am currently searching for an easy way to find specific patterns in our projects, because we were really sloppy with our localization... It would be great if the solution could be a Visual Studio extension that produces warnings in the error list, so that every team member can see directly that he/she is missing a translation.

I have started looking into extension using this example: https://github.com/Microsoft/VSSDK-Extensibility-Samples/tree/master/ErrorList But I am not sure if this is the right approach and how I can combine that with a pattern search instead of spelling errors.

Any help or idea is much appreaciated.


Solution

  • I can help you to write errors in the Visual Studio Error List(I did it in my VS extension), but I don't know how to find specific patterns in a project. 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 a "ErrorWindowController". The code looks like this:

    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
    
    }