在C#中,如何传递 IServiceProvider 到 ErrorListProvider(IServiceProvider isp) 中?

huangapple go评论75阅读模式
英文:

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

问题

我正在创建一个VSIX项目,在其中需要在错误列表窗口中添加一些自定义错误。现在我卡在了IServiceProvider上。它包含什么以及为什么我需要它,以及我如何获取它?在我的代码中,我需要用一个服务提供程序来初始化。我该怎么做?以下是代码:

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
        });
    }
}

请帮助。我是C#和VSIX的初学者。谢谢!

英文:

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!

答案1

得分: 1

您的包是一个服务提供程序。它的基类AsyncPackage派生自Package类,该类实现了OLE.Interop.IServiceProvider和System.IServiceProvider(是的,VSX很令人困惑,有两个IServiceProvider接口)。因此,您可以从您的包类中调用ErrorListManager.Initialize(this)。

话虽如此,您可能希望在VS 2015及更高版本中使用ErrorList的新API。您目前使用的旧方法不允许您向"Code"等列添加值。请参考以下示例:

VSSDK-Extensibility-Samples/ErrorList: https://github.com/microsoft/VSSDK-Extensibility-Samples/tree/master/ErrorList

madskristensen/WebAccessibilityChecker: https://github.com/madskristensen/WebAccessibilityChecker/tree/master/src/ErrorList

madskristensen/TaskOutputListener: https://github.com/madskristensen/TaskOutputListener/blob/master/src/ErrorListProvider/ErrorListProvider.cs

英文:

Your package is a service provider. Its base class AsyncPackage derives from the Package class which implements OLE.Interop.IServiceProvider and System.IServiceProvider (yes, VSX is confusing and there are two IServiceProvider interfaces). So, from your package class you would call ErrorListManager.Initialize(this).

That said, you may want to use the new API of VS 2015 and higher for the ErrorList. The old approach that you are using doesn't allow you to add values to columns such as "Code", etc. See samples here:

VSSDK-Extensibility-Samples/ErrorList: https://github.com/microsoft/VSSDK-Extensibility-Samples/tree/master/ErrorList

madskristensen/WebAccessibilityChecker: https://github.com/madskristensen/WebAccessibilityChecker/tree/master/src/ErrorList

madskristensen/TaskOutputListener: https://github.com/madskristensen/TaskOutputListener/blob/master/src/ErrorListProvider/ErrorListProvider.cs

答案2

得分: 1

要在VS错误列表中写入内容,您需要使用ErrorListProvider。在我的实现中,我继承了ErrorListProvider并为"ErrorWindowController"实现了自己的行为。代码如下(请阅读代码注释以获取更多信息):

public class ErrorWindowController : ErrorListProvider
{
    #region Constructor

    /// <summary>
    /// 实例构造函数
    /// </summary>
    /// <param name="aIServiceProvider"></param>
    public ErrorWindowController(IServiceProvider aIServiceProvider) : base(aIServiceProvider)
    {
    }

    #endregion

    #region Public Methods

    // 使用此方法将自定义错误集合添加到VS错误列表中
    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();
    }

    // 移除与项目依赖关系的错误列表中的所有错误,当特定项目关闭时
    // 或在关闭VS解决方案时移除错误列表中的所有错误
    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();
    }

    // 从错误列表中移除所有错误
    public void Clear()
    {
        Tasks.Clear();
    }

    #endregion

    #region Private Methods

    // 这是可选的
    // 为您的错误添加导航
    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
}

ErrorModel 非常简单:

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
}

愉快的编码!

英文:

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
/// &lt;summary&gt;
/// Instance Constructor
/// &lt;/summary&gt;
/// &lt;param name=&quot;aServiceProvider&quot;&gt;&lt;/param&gt;
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&lt;ErrorModel&gt; 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 &gt;= 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!

huangapple
  • 本文由 发表于 2020年1月3日 18:23:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/59576846.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定