24

我将 Visual Studio 2012 用于具有 C# 和 C++/CLI .dll 的解决方案,其中 C++/CLI dll 引用本机 .dll,例如 boost。C++ 代码编译为 x64。

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

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

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

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

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

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

经过一番测试,我发现这里的反派是vstest.executionengine.exe。使用句柄(来自 SysInternals),我看到 vstest.executionengine.exe 持有 cli-dll 的 .dll 和 .pdb 的锁。它不为仅限托管的 dll 持有任何锁。

测试运行完成后,如何让 Visual Studio 测试资源管理器释放 C++/Cli dll 上的锁?

4

6 回答 6

30

在 Visual Studio 2013 中,可以通过取消选中菜单中“测试 -> 测试设置”下的“保持测试执行引擎运行”选项轻松解决此问题。

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

于 2014-08-23T20:21:50.667 回答
9

经过一番搜索,我在 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 文件的锁定。

于 2013-05-24T10:33:09.660 回答
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.
    }
}
于 2014-03-04T10:45:07.897 回答
2

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

去掉勾选

在测试运行之间保持测试执行引擎运行

选项位于

工具/选项/Web 性能测试工具

于 2014-02-18T09:42:30.843 回答
1

我已经编写了一个 C# 实用程序,以便能够在此处加载和卸载本机库, 我在测试项目中使用了它,如下所示。由于它在 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();
        //...
    }
}
于 2014-04-03T06:56:51.237 回答
1

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

要修复这种情况,首先杀死现有的 vstest.executionengine.exe,修改 TFS Build 代理使用的用户以使用您登录的用户执行。打开存储在 TFS 构建代理工作区中的解决方案并取消选择该选项。之后,TFS Build 代理将读取“keep test execution engine”选项,因为 SUO 文件是针对同一用户的。

于 2016-01-21T12:25:41.587 回答