20
  • Visual Studio 2012
  • SQLite 1.0.82.0 (from nuget)

I am trying to use the "Run All" command in the "Test Explorer" The following error happens after you run the test once ... after that it will not build anymore, until you restart visual studio

Here is the build error

The Process cannot access the file 'SQLite.Interop.dll' because it is being used by another process

here is the code

using System.Data.SQLite;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Test.Sqlite
{
    [TestClass]
    public class Test_Sqlite_Locking
    {
        [TestMethod]
        public void can_create_table()
        {
            using(var fact = new SQLiteFactory())            
            using (var conn = fact.CreateConnection())
            {
                conn.ConnectionString = "Data Source=:memory:;Version=3;New=True;";
                conn.Open();
                //conn.Close();                
            }

            //SQLiteConnection.ClearAllPools();
            //GC.Collect();
        }
    }
}

I have tried, closing connection, calling ClearAllPools, GC.Collect, and creating the SQLiteConnection directly (instead of the Factory) ... still same issue

This DOES work if you DEBUG ALL TESTS ... but it is when you just Run the tests that this seems to lock it up

ObeseCoder
  • 391
  • 2
  • 6
  • Can you wrap a Try Catch around the conn.open and see what the error are you trying to maintain that connection..? if so after the connection it should be Disposed of being that you have it wrapped inside a using{} – MethodMan Oct 16 '12 at 16:49
  • I have tried that ... but this error is a BUILD error ... not a runtime error ... and it only happens after you 'Run' the tests, after that it appears Visual Studio still has something open, and the library file is locked – ObeseCoder Oct 16 '12 at 17:11
  • which line does it error on .. ? the using(var fact = new SQLiteFactory()) – MethodMan Oct 16 '12 at 17:14
  • can you paste what the config section looks like should look something like this – MethodMan Oct 16 '12 at 17:21
  • there is no app.config ... here is the full error "Warning 1 Could not copy "D:\Code\Test.Sqlite\Test.Sqlite\x86\SQLite.Interop.dll" to "bin\Debug\x86\SQLite.Interop.dll". Beginning retry 1 in 1000ms. The process cannot access the file 'bin\Debug\x86\SQLite.Interop.dll' because it is being used by another process. Test.Sqlite " – ObeseCoder Oct 16 '12 at 17:35
  • can you copy the DLL's manually and restart your machine..? – MethodMan Oct 16 '12 at 17:36
  • it works 1 time after i restart visual studio ... if i try a clean before i build, i get a similar error that the file is in use – ObeseCoder Oct 16 '12 at 17:37
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/18119/discussion-between-obesecoder-and-dj-kraze) – ObeseCoder Oct 16 '12 at 17:39
  • can GAC the DLL's or set the property on the DLL to copy Local here is a stackoverflow link that you can reference.. http://stackoverflow.com/questions/9725979/unable-to-find-the-requested-net-framework-data-provider-sqlite also how are you closing the program down when testing it..? it would be nice to see more code..I am sure that there is something else going on ... – MethodMan Oct 16 '12 at 17:40
  • that is all of the code ... it is a visual studio test framework unit test class library ... my dlls are set to copy local – ObeseCoder Oct 16 '12 at 17:47
  • Ok one last thing.. is this 4.0 or 3.5 framework.. try setting it to 3.5 save it then turn around and change the project properties page setting back to 4.0 – MethodMan Oct 16 '12 at 17:57
  • I can only suggest one other thing but you will need to change the code a bit.. I will post what I know works for me when I connect to SQL Lite – MethodMan Oct 16 '12 at 18:00

8 Answers8

32

I could not find that option in VS2012 (at least not for standard unit tests), therefore I came up with another solution:

The problem you are facing comes from the fact that the unit test runner remains loaded so that repeated test runs are faster. Since SQLite.Interop.dll will probably not change too often, I changed the CopyToOutputDirectory option to PreserveNewest rather than the default Always.

You can do this by opening the properties (F4) view and selecting the SQLite.Interop.dll file in your solution. The only time this will probably still lock up is when you upgrade to a newer version of SQLite and restarting VS2012 then works OK for me.

Philipp Aumayr
  • 1,400
  • 11
  • 14
  • 1
    Unfortunately, this doesn't work if SQLite is referenced by a test dependency instead of the test assembly itself. – skolima Jan 08 '13 at 09:32
  • Worked for my setup. sqlite is ref'd by test package. – longday Feb 27 '13 at 03:06
  • 1
    This is the only answer that works in VS2013, so please mark this as the correct answer. The only way is to avoid to copy the .dll on the output folder. – Raffaeu Aug 23 '13 at 11:58
  • I was wondering why I was starting to encounter this on a new project when I have similar projects referencing System.Data.SQLite. The difference? This one I setup through the nuget package. You're totally correct. Within my test project, I just set the x86/x64 SQLite.Interop.dll files to CopyIfNewer. Thanks! – Dev Leader Jul 05 '14 at 18:04
  • 1
    @DevLeader, how do you set the option to CopyToOutputDirectory with NuGet? I can only set Copy Local to true or false.. – Maria Ines Parnisari Nov 19 '15 at 14:00
  • @miparnisari looks like things may have changed a bit (I'm looking in VS2015 now though). I don't even see the interop files listed in the solution... Sorry it's been long enough that I can't recall what I had seen at the time. – Dev Leader Nov 19 '15 at 22:13
13

I worked around this by using the following as a pre-build event on the affected test projects:

for 64-bit:

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

or for 32-bit:

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

This silently kills the execution engine before building the test project. The /FI "MEMUSAGE gt 1" stops the command (and therefore the build) from failing if the execution engine isn't running.

Arjailer
  • 791
  • 7
  • 10
  • 2
    For me, it was the discovery engine that was the problem. So I used this line: taskkill /F /IM vstest.discoveryengine.x86.exe /FI "MEMUSAGE gt 1" – Brandon S Nov 13 '13 at 23:46
  • This just solved the issue for me as well. Seems like this should be marked as the correct answer. – Nat Mar 16 '17 at 18:27
8

Try this:

  • In VS.NET, click on Tools \ Options
  • When the dialog appears, click on "Test Tools"
  • Click on "Test Execution"
  • Uncheck the box "Keep test execution engine running between tests"
  • Click OK and restart VS.NET

You should be able run SQLite based tests now without having to restart.

MB.
  • 164
  • 1
  • 3
4

In Visual Studio 2013 - Go to "Test > Test Settings > keep Test Execution Engine Runing" and uncheck it! Works for me.

2

The workaround provided by Philipp Aumayr (set CopyToOutputDirectory option to PreserveNewest rather than the default Always) works for most scenarios, but not all, unfortunately. As other questions on SO point out, the fact that vstest.executionengine does not terminate is a common issue in VS2012 - worse, Microsoft developers treat this as a feature and by design. The option to prevent this behavior existed in VS2010 but has been removed in VS2012.

If you too have a problem with this "improvement" then please vote on the Microsoft Connect support issue vstest.executionengine.x86.exe (32 bit) - Not Closing (affects both x86 and x64 despite the title).

Community
  • 1
  • 1
skolima
  • 31,963
  • 27
  • 115
  • 151
2

I know this question is old, but I had this problem and some of the answers here sparked an idea. One of the first problems I encountered when trying to build unit/integration tests around SQLite was that MSTest (which we use for scripted builds) wasn't deploying all of the necessary dependencies to the test run's "Out" directory before running the test, so the tests failed. The best way I found to solve this problem was to add these attributes to my test class:

[TestClass]
**[DeploymentItem("System.Data.SQLite.dll")]
[DeploymentItem("x86\\SQLite.Interop.Dll")]**
public class TestClass

This appears to also solve this issue...I'm guessing this causes VSTest to load a different copy of these dependencies so that VSBuild can still do what it will with the copy in your normal /bin/ directory.

Brandon
  • 173
  • 11
0

Also make sure that your Database is installed to the correct folder
SQLite Connection Strings

Data adapter that you may want to try as well using SQL Lite Using SQLitew with .NET

SQLiteConnectionStringBuilder builder = new SQLiteConnectionStringBuilder();
builder.FailIfMissing = true;
builder.DataSource = "Insert the fully qualified path to your sqlite db";
SQLiteConnection connection = new SQLiteConnection(builder.ConnectionString);
try
{
  connection.Open();
}
catch(SqlException exp)
{
    // Log what you need from here.
    throw new InvalidOperationException("Whatever exception you want to throw", exp);
}

Read this Article to see if it helps to correct your issue as well System.Data.SQLite.View Ticket

MethodMan
  • 18,625
  • 6
  • 34
  • 52
  • yeah tried that same issue ... i think it something to do with the visual studio unit test framework runner ... it must not be closing the sqlite.interop.dll correctly when you do a 'run all' – ObeseCoder Oct 16 '12 at 18:26
  • Checkout this StackOverFlow link as well http://stackoverflow.com/questions/3787428/loading-x86-or-x64-assembly – MethodMan Oct 16 '12 at 22:00
  • I added another link Using SQLLite with .NET – MethodMan Oct 16 '12 at 22:03
0

Try disposing of the connection as below. It worked fine for me.

    private void Dispose(bool disposing)
    {
        if (_disposed) return;

        if (disposing)
        {
            if (_dbConnection != null)
            {
                _dbConnection.Cancel();
                _dbConnection.Close();
                _dbConnection.Dispose();
            }
        }

        _disposed = true;
    }