Visual Studio 2015 测试运行程序中的“句柄无效”异常

Posted

技术标签:

【中文标题】Visual Studio 2015 测试运行程序中的“句柄无效”异常【英文标题】:"The handle is invalid" exception in Visual Studio 2015 test runner 【发布时间】:2015-10-19 23:27:29 【问题描述】:

我发现我在 VS2013 中通过的一个测试在 VS2015 中失败了,该测试调用了一个服务,其中包括对 Console.Clear(); 的调用

为了了解发生了什么,我做了一个简单的单元测试

   [TestMethod]
    public void ExampleTest()
    
        Console.Clear();
    

此测试在 Visual Studio 2013 中通过,但在 2015 年出现以下错误:

测试名称:ExampleTest 测试全名:solution.Common.Test.CacheManagerTest.ExampleTest 测试源:C:\solution.Common.Test\CacheManagerTest.cs:第 34 行 测试结果:失败 测试时间:0:00:00.3015003

结果 StackTrace:在 System.IO.__Error.WinIOError(Int32 errorCode, System.Console.GetBufferInfo(Boolean) 处的字符串可能全路径 throwOnNoConsole, Boolean& 成功)在 System.Console.Clear() 在 sol.Common.Test.CacheManagerTest.ExampleTest() 中 C:\solution.Common.Test\CacheManagerTest.cs:第 35 行结果消息: 测试方法 Alexandria.Common.Test.CacheManagerTest.ExampleTest 抛出 异常:System.IO.IOException:句柄无效。

我明白,如果我的服务没有被控制台调用,它会失败是一种糟糕的设计。我问这个问题的原因是为了理解为什么在新版本中失败了的 Visual Studio。这是预期的行为吗?发生了什么变化?

我在更改日志中没有看到任何与此相关的明显内容。

编辑:我从以下 dll 调用 Console.clear

Microsoft\Framework.NETFramework\v4.5.1\mscorlib.dll

编辑 2:

两个视觉工作室中的 testproject 属性图片

【问题讨论】:

不。对我来说,这在 Visual Studio 2010 上失败了。您能否再次检查 VS2013 右键单击​​您的项目,选择属性 -> 选择应用程序选项卡 -> 检查输出类型。是说类库吗? @gideon 是的,它是一个类库 i.imgur.com/1Vedgyd.png 我正在使用 Microsoft Visual Studio Professional 2013 版本 12.0.31101.00 更新 4 哇,这很奇怪。它应该会中断,因为当它是类库时没有可用的控制台。是否有效,并清除控制台? @mmilan 您在测试项目中使用什么“.net 框架”?在 '.net 4.5' console.clear() 使用 Console.GetBufferInfo() 而不是 Console.GetBufferInfo(Boolean throwOnNoConsole, Boolean& succeeded) 作为你的调用堆栈。 @gideon 我还没有找到一种方法来实际检查它是否确实清除了控制台。对我来说,在 Vs2013 中通过测试是没有意义的,但确实如此。 【参考方案1】:

VS2015 中的变化非常明显,使用测试 > 调试 > 所有测试来获得洞察力。可以看到它现在有了一个新的测试宿主进程,它的名字是TE.ProcessHost.Managed.exe,存放在C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TestWindow目录下。

以前版本的 VS 使用不同的主机 vstest.executionengine.exe。新测试主机的一个显着变化是它不再是控制台模式程序。通过在 exe 上运行 Dumpbin.exe /headers 可以看到一些内容。

查看潜在问题的另一种方法是使用任务管理器。请注意在较旧的 VS 版本中运行测试如何导致添加 conhost.exe 进程。这是拥有控制台模式应用程序的控制台窗口的进程。我之前看到的一个问题是这个过程往往会泄漏,而不是在测试完成时终止。添加更多的 conhost.exe 实例,在研究这个问题时,我运行了 12 个实例。据推测,VS2015 中的更改旨在解决该问题。

从技术上讲,您可以使用a .runsettings file 配置单元测试,并使用<ForcedLegacyMode> 元素强制使用旧的测试主机进程。然而,这对该测试的结果没有影响,看起来他们以多种方式解决了这个问题。

这是相当多的猜测,我建议您使用 connect.microsoft.com 提交反馈报告。您可以引用此 Q+A 以供参考。


同时,您可以考虑一种解决方法。请注意Console.Clear() 通常是一个麻烦制造者,当控制台模式应用程序的输出被重定向时,它也会在正常使用中失败。使用> 操作符在命令行提示符下很容易做到。这是它在单元测试中失败的最终原因。您需要使代码具有弹性,以便它可以在生产和单元测试中正常工作。像这样:

    if (!Console.IsOutputRedirected) Console.Clear();

这需要针对 .NET 4.5 或更高版本。如果您需要针对早期版本,可以使用this SO post 中的代码。

【讨论】:

以上是关于Visual Studio 2015 测试运行程序中的“句柄无效”异常的主要内容,如果未能解决你的问题,请参考以下文章

MSTest Visual Studio 2015:未找到测试容器直接或间接引用的程序集或模块“xxxxxxx”

Visual Studio 2015 MSTest 无法运行负载测试

使用 Visual Studio 2015 测试 Citrix 应用程序

visual studio 2015 文件夹运行程序在哪

visual studio 2015 文件夹运行程序在哪

程序在 Visual Studio 之外无法运行