Question

I am using Visual Studio 2012 for a solution with a C# and a C++/CLI .dll, with the C++/CLI dll referencing native .dlls such as boost. The C++ code is compiled as x64.

When I open VS, I can clean and build my project.

Using test explorer, I can run my tests.

As soon as I've used test explorer to run tests once, I cannot rebuild the project. It seems that VS2012 Test Explorer keeps a lock on my C++/CLI-dll, and there I get the following error:

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

As a result of this, whenever I have run the tests using Test Explorer, I need to restart VS2012 before I can continue developing. Obviously this is not a sustainable development process.

Testing and rebuilding works without problem with C#-only dlls - as far as I can tell the problem only occurs with DLLs that use native x64 code.

After some more testing, I found that the villain here is vstest.executionengine.exe. Using handle (from SysInternals), I see that vstest.executionengine.exe holds locks for the .dll and the .pdb of the cli-dll. It does not hold any locks for managed-only dlls.

How can I get Visual Studio Test Explorer to release the locks on the C++/Cli dlls after the test runs completed?

Was it helpful?

Solution 2

After some more searching, I found this post on connect.microsoft.com. The last hint in workarounds does solve the problem, although it's an ugly hack.

I can rebuild if I add the following as pre-build events to my C++/CLI dll:

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

This will kill the vstest.executionengine.exe process, thereby freeing the lock on my .dll file.

OTHER TIPS

In Visual Studio 2013 this problem can easily be fixed by unchecking the option "Keep Test Execution Engine Running" under "Test -> Test Settings" in the menu.

I found the answer in another post: vstest.executionengine.x86.exe not closing

I've also encountered this issue while testing involving native dlls. The workaround (solution?) I found was to add a DeploymentItemAttribute to the tests - not sure if this is generally true, but it certainly worked for me. It's a bit of a pain if there are lots of them (I had 6 in my case), but once done it was easy to copy and paste to the other tests.

So my unit test class looks something like this:

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

I've also been fighting this problem and initially used the "taskkill" workaround, but I just stumbled over an option in the VS2013 settings which seems to more elegantly solve this problem:

Remove the check-mark on the

Keep test execution engine running between test runs

option found at

Tools / Options / Web Performance Test Tools

I had written a C# utility to be able to load and unload native libraries in here I used it in the test project as below. Since it unloads dll in Dispose, I don't get build errors.

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();
        //...
    }
}

Adding some stuff to the answer of @frodesto, (in case of VS2013), "Test>Test Setting>Keep Test Executin Engine running" configuration is stored in the user configuration (SUO file). This can be a bit nasty in case of this error happens in the TFS Build agent, beacause it uses a service default user.

To fix this case, first kill the existing vstest.executionengine.exe, modify the user used by TFS Build agent to execute with the user you are logged on. Open the solution stored in TFS Build agent workspace and unselect the option. After that, TFS Build agent will read the "keep test execution engine" option beacause the SUO file is for the same user.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top