VS2012测试资源管理器锁定本机.dll,使重建失败

时间:2013-05-24 09:51:46

标签: c# visual-studio visual-studio-2012 c++-cli test-explorer

我正在使用Visual Studio 2012获得带有C#和C ++ / CLI .dll的解决方案,其中C ++ / CLI dll引用本机.dll,例如boost。 C ++代码编译为x64。

当我打开VS时,我可以清理并构建我的项目。

使用测试资源管理器,我可以运行我的测试。

一旦我使用测试资源管理器运行测试一次,我就无法重建项目。似乎VS2012 Test Explorer会锁定我的C ++ / CLI-dll,并且出现以下错误:

LNK1104: cannot open file 'C:\Dev\LockExample\bin\Debug\cli.dll'

因此,每当我使用Test Explorer运行测试时,我需要重新启动VS2012才能继续开发。显然,这不是一个可持续发展的过程。

测试和重建工作没有问题C#-only dll - 据我所知,问题只发生在使用本机x64代码的DLL上。

经过一些测试,我发现这里的反派是vstest.executionengine.exe。使用句柄(来自SysInternals),我看到vstest.executionengine.exe保存了.dll和cli-dll的.pdb的锁。对于托管专用dll,它没有任何锁定。

如何在测试运行完成后让Visual Studio Test Explorer释放C ++ / Cli dll上的锁?

6 个答案:

答案 0 :(得分:30)

在Visual Studio 2013中,可以通过取消选中菜单中“Test - > Test Settings”下的“Keep Test Execution Engine Running”选项轻松解决此问题。

我在另一篇文章中找到了答案: vstest.executionengine.x86.exe not closing

答案 1 :(得分:9)

经过一番搜索后,我找到了this post on connect.microsoft.com。解决问题的最后一个提示确实解决了问题,尽管这是一个丑陋的黑客攻击。

如果我将以下内容添加到我的C ++ / CLI DLL中,我可以重建:

taskkill /F /IM vstest.executionengine.exe /FI "MEMUSAGE gt 1"
taskkill /F /IM vstest.executionengine.x86.exe /FI "MEMUSAGE gt 1"

这将终止vstest.executionengine.exe进程,从而释放我的.dll文件上的锁。

答案 2 :(得分:3)

我在测试涉及本机dll时也遇到过这个问题。我找到的解决方法(解决方案?)是将一个DeploymentItemAttribute添加到测试中 - 不确定这一般是否正确,但它确实对我有用。如果它们很多(我的情况下有6个),这有点痛苦,但一旦完成,很容易复制并粘贴到其他测试中。

所以我的单元测试类看起来像这样:

[TestClass]
public class TestMyClass
{
    [TestMethod]
    [DeploymentItem("firstnative.dll")]
    [DeploymentItem("secondnative.dll")]
    public void TestMyMethod()
    {
        //Code which (indirectly) uses the above native dlls.
    }
}

答案 3 :(得分:2)

我也一直在解决这个问题并且最初使用了“taskkill”解决方法,但我只是偶然发现了VS2013设置中的一个选项,它似乎更优雅地解决了这个问题:

删除

上的复选标记

让测试执行引擎在测试运行之间运行

找到

选项

工具/选项/网络效果测试工具

答案 4 :(得分:1)

我编写了一个C#实用程序,可以在here中加载和卸载本机库 我在测试项目中使用它如下。由于它在Dispose中卸载了dll,因此我不会出现构建错误。

public interface INativeCrypto : INativeImport
{
    [ImportFunction("mynative.dll"]
    int NativeMethod();
}


[TestClass]
public class UnitTest1
{
    public void TestMethod1()
    {
        INativeCrypto impl = NativeImport.Create<INativeCrypto>("");

        // Use methods in impl
        int i = impl.NativeMethod();
        //...
    }
}

答案 5 :(得分:1)

在@frodesto的答案中添加一些东西,(在VS2013的情况下),&#34;测试&gt;测试设置&gt;保持测试Executin引擎运行&#34;配置存储在用户配置(SUO文件)中。如果在TFS Build代理中发生此错误,这可能有点令人讨厌,因为它使用服务默认用户。

要解决此问题,请首先终止现有的vstest.executionengine.exe,修改TFS Build代理程序使用的用户,以便与您登录的用户一起执行。打开存储在TFS Build Agent工作区中的解决方案,然后取消选择该选项。 之后,TFS Build代理将读取&#34;保持测试执行引擎&#34;选项因为SUO文件是针对同一个用户的。