C# 在Visual Studio扩展中使用DTE2接口接收测试运行开始/结束

C# 在Visual Studio扩展中使用DTE2接口接收测试运行开始/结束,c#,visual-studio,visual-studio-extensions,C#,Visual Studio,Visual Studio Extensions,在VisualStudioExtension中是否有订阅测试资源管理器事件的方法? 我在DTE2接口中没有找到类似的内容。我的目标是在测试运行完成时从扩展中触发一些函数(对于从测试资源管理器运行的测试) 谢谢大家! 谢谢你的回答。使用应用程序对象DTE的工作代码: using System.ComponentModel.Composition; using Microsoft.VisualStudio.TestWindow.Extensibility; using Microsoft.Visua

在VisualStudioExtension中是否有订阅测试资源管理器事件的方法? 我在DTE2接口中没有找到类似的内容。我的目标是在测试运行完成时从扩展中触发一些函数(对于从测试资源管理器运行的测试)


谢谢大家!

谢谢你的回答。使用应用程序对象DTE的工作代码:

using System.ComponentModel.Composition;
using Microsoft.VisualStudio.TestWindow.Extensibility;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TestTools.Execution;

public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInst, ref Array custom)
{            
    Microsoft.VisualStudio.OLE.Interop.IServiceProvider InteropServiceProvider = application as Microsoft.VisualStudio.OLE.Interop.IServiceProvider;
    _ServiceProvider = new ServiceProvider(InteropServiceProvider);
    _ComponentModel = (IComponentModel)_ServiceProvider.GetService(typeof(SComponentModel));
    _OperationState = _ComponentModel.GetService<IOperationState>();
    _OperationState.StateChanged += _OperationState_StateChanged;
}

void _OperationState_StateChanged(object sender, OperationStateChangedEventArgs e)
{            
}
使用System.ComponentModel.Composition;
使用Microsoft.VisualStudio.TestWindow.Extensibility;
使用Microsoft.VisualStudio.ComponentModelHost;
使用Microsoft.VisualStudio.Shell;
使用Microsoft.VisualStudio.TestTools.Execution;
public void OnConnection(对象应用程序、Extensibility.ext\u ConnectMode ConnectMode、对象加载项、ref数组自定义)
{            
Microsoft.VisualStudio.OLE.Interop.IServiceProvider InteropServiceProvider=作为Microsoft.VisualStudio.OLE.Interop.IServiceProvider的应用程序;
_ServiceProvider=新的ServiceProvider(InteropServiceProvider);
_ComponentModel=(IComponentModel)_ServiceProvider.GetService(typeof(scoComponentModel));
_OperationState=_ComponentModel.GetService();
_OperationState.StateChanged+=\u OperationState\u StateChanged;
}
void\u OperationState\u StateChanged(对象发送方,OperationStateChangedEventArgs e)
{            
}
还可以通过ITestsService访问当前发现的测试

_TestsService = _ComponentModel.GetService<Microsoft.VisualStudio.TestWindow.Extensibility.ITestsService>();

var GetTestTask = _TestsService.GetTests();
GetTestTask.ContinueWith(Task =>
{
    var DiscoveredTests = Task.Results.ToList();
});
\u TestsService=\u ComponentModel.GetService();
var GetTestTask=_TestsService.GetTests();
GetTestTask.ContinueWith(任务=>
{
var DiscoveredTests=Task.Results.ToList();
});

您需要的接口可以通过Microsoft.VisualStudio.TestWindow.interfaces.dll程序集中的MEF获得

您需要通过MEF和
[Import]
一个
IOperationState
实例公开扩展,或者使用
IComponentModel
接口(为
SComponentModel
服务返回)访问
IOperationState
。从那里,您希望向
IOperationState.StateChanged
事件添加事件处理程序,并查找
State
属性以包含
TestOperationStates.TestExecutionFinished
标志

我非常抱歉没有链接,但是我在MSDN中找不到任何关于这个的信息

编辑:关于兼容性的两条评论。

  • 这仅在Visual Studio 2012及更高版本中可用
  • 必要的程序集(如上所述)在两个版本的Visual Studio中具有不同的强名称,并且在Visual Studio 2013中没有
    bindingRedirect
    。这意味着您将被迫为Visual Studio 2012和Visual Studio 2013部署单独的扩展,或者对动态加载扩展代码的方式变得“聪明”(后者远远超出了这个答案的范围,但我已经在一些情况下使用了它,比如需要访问特定于版本的IntelliSense资源的继承边距扩展)
  • 样本与2017年的对比

    使用MEF和ITestContainerDiscoverer导出类型的示例。但请注意,这可能会在VS2019中消失

    [Export(typeof(ITestContainerDiscoverer))]
    [Export(typeof(Testything))]
    internal class Testything : ITestContainerDiscoverer
    {
    
        [ImportingConstructor]
        internal Testything([Import(typeof(IOperationState))]IOperationState operationState)
        {
            operationState.StateChanged += OperationState_StateChanged;
         }
    
        public Uri ExecutorUri => new Uri("executor://PrestoCoverageExecutor/v1");
    
    
        public IEnumerable<ITestContainer> TestContainers
        {
            get
            {
                return new ITestContainer[0].AsEnumerable();
            }
        }
    
    
        public event EventHandler TestContainersUpdated;
    
        private void OperationState_StateChanged(object sender, OperationStateChangedEventArgs e)
        {
            if (e.State == TestOperationStates.TestExecutionFinished)
            {
                var s = e.Operation;
            }
        }
    }
    
    [导出(类型(ITestContainerDiscoverer))]
    [导出(typeof(Testything))]
    内部类测试:ITestContainerDiscoverer
    {
    [导入构造函数]
    内部测试([导入(类型(IOperationState))]IOperationState操作状态)
    {
    operationState.StateChanged+=operationState_StateChanged;
    }
    公共Uri执行器Uri=>新Uri(“executor://PrestoCoverageExecutor/v1");
    公共IEnumerable测试容器
    {
    得到
    {
    返回新的ITestContainer[0]。AsEnumerable();
    }
    }
    公共事件事件处理程序TestContainers更新;
    私有void操作state_StateChanged(对象发送方,操作stateChangedEventArgs e)
    {
    if(e.State==TestOperationStates.TestExecutionFinished)
    {
    var s=e.操作;
    }
    }
    }
    
    在这里可以找到更多的东西

    这不能完全回答OP的问题question@Verdolino为什么不呢?在OperationState_StateChanged事件中,可以检查e.State==TestOperationStates.TestExecutionFinished。@JoanComasFdz完全正确。答案中缺少这一点。他粘贴了所有需要知道测试状态的代码。这就是问题所在。第二件事是y我们的“目标”。我记得它在VS2012更新3或4上对我有效。谢谢你的回答。写了一篇关于如何做到这一点的小帖子。它工作得很好,谢谢。你知道如何获得resharper事件吗?我只看到OperationSetStarted/Finished之间没有任何其他事件…更新了你的答案,因为我正在研究如何使用扩展来实现这一点,我正在尝试b发布的代码基于中使用的示例工作