I am using the MSBuild runner in TeamCity to build an ASP.net web api and running unit tests. Everything was working, until I upgraded to "Microsoft Build Tools 2017 15.7.2".
Suddenly msbuild was copying an older version of Newtonsoft.Json.dll (version 6.0.4.17603) from either "C:\Program Files (x86)\ISS\Microsoft Web Deploy V3" or "C:\Program Files\ISS\Microsoft Web Deploy V3" to the output folder when building the solution. All the projects are referencing the 9.0.1 version using NuGet.
Monitoring the output folder as the build was running, I could see the .dll switching back and forth between 6.0.4 and 9.0.1 until the build ended, and the 6.0.4 version remained.
I found this question and when I renamed the Newtonsoft.Json.dll files in the Web deploy folders to Newtonsoft.Json_old.dll", msbuild did not replace my 9.0.1 version and everything was working fine.
I have checked that all the projects referencing to Newtonsoft.Json are referencing the 9.0.1 version and using the correct Hint-Path in .csproj files.
Does anyone have any idea how to solve the problem? My solution seems more like a workaround and I would like to know why msbuild was copying this file in the first place.
Summary
When MSBuild is resolving assemblies, it will search in some pretty weird directories, including that Web Deploy folder, depending on what you have installed. Based on the MSBuild reference, I believe that this is legacy behavior. You can stop it from doing that with an MSBuild property defined in your project file.
In the affected project file, find the following line:
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
And add this below it:
<PropertyGroup>
<AssemblySearchPaths>$(AssemblySearchPaths.Replace('{AssemblyFolders}', '').Split(';'))</AssemblySearchPaths>
</PropertyGroup>
This will cause MSBuild to no longer look in the problematic folders when resolving assemblies.
Full Story
My team ran into a similar problem when we moved to Visual Studio 2019. Some of our projects are still targeting .NET Framework 4.0, and after installing Visual Studio 2019 on our build agents, we started getting a mysterious error with projects that referenced some of our core libraries:
The primary reference "OurCoreLibrary, Version=3.4.2.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx, processorArchitecture=MSIL" could not be resolved because it has an indirect dependency on the assembly "Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed" which was built against the ".NETFramework,Version=v4.5" framework. This is a higher version than the currently targeted framework ".NETFramework,Version=v4.0".
The problem went away upon switching the project to target 4.5, but for reasons I won't get into here, we couldn't do that for every affected project, so I decided to dig in a bit deeper.
As it turns out, your question offered some insight into what was going on. The version of Newtonsoft.Json that we were referencing matched the version in "C:\Program Files (x86)\IIS\Microsoft Web Deploy V3", and when I removed the file, the build succeeded.
Our specific problem was that the copy of Newtonsoft.Json in the Web Deploy folder was the same version (9.0.0.0) but the wrong framework (4.5 instead of 4.0), and for whatever reason the resolution logic doesn't check the target framework, causing a mismatch at build time. Updating to VS2019 involved updating Web Deploy, which also updated that copy of Newtonsoft.Json to 9.0.0.0, causing our collision.
To see why that assembly was even being looked at to begin with, I set the MSBuild project build output verbosity to Diagnostic and took a look at what was happening. Searching for the offending path showed that in the ResolveAssemblyReferences task, MSBuild was going through some unexpected places to find matches:
1> For SearchPath "{AssemblyFolders}". (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft.NET\ADOMD.NET\140\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.0\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\v3.5\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files\IIS\Microsoft Web Deploy V3\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.winmd", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.dll", but it didn't exist. (TaskId:9)
1> Considered "C:\Program Files (x86)\Microsoft SQL Server\140\SDK\Assemblies\OurCoreLibrary.exe", but it didn't exist. (TaskId:9)
Further digging shows that the paths searched are passed in as AssemblySearchPaths, which is defined in Microsoft.Common.CurrentVersion.targets:
<AssemblySearchPaths Condition=" '$(AssemblySearchPaths)' == ''">
{CandidateAssemblyFiles};
$(ReferencePath);
{HintPathFromItem};
{TargetFrameworkDirectory};
$(AssemblyFoldersConfigFileSearchPath)
{Registry:$(FrameworkRegistryBase),$(TargetFrameworkVersion),$(AssemblyFoldersSuffix)$(AssemblyFoldersExConditions)};
{AssemblyFolders};
{GAC};
{RawFileName};
$(OutDir)
</AssemblySearchPaths>
According to the MSBuild Task Reference for the ResolveAssemblyReferences task, SearchPaths parameter is defined as:
Specifies the directories or special locations that are searched to find the files on disk that represent the assemblies. The order in which the search paths are listed is important. For each assembly, the list of paths is searched from left to right. When a file that represents the assembly is found, that search stops and the search for the next assembly starts.
...and it defines a few special constants, including our friend {AssemblyFolders}:
{AssemblyFolders}: Specifies the task will use the Visual Studio.NET 2003 finding-assemblies-from-registry scheme.
Because the directories are checked in order, you might expect {HintPathFromItem} to take precedence, and in most cases it does. However, if you have a dependency with a dependency on an older version of Newtonsoft.Json, there won't be a HintPath for that version and so it will continue on until it resolves.
Later on in Microsoft.Common.CurrentVersion.targets we can see that there are cases where this constant is explicitly removed, which is where the answer above comes from:
<PropertyGroup Condition="'$(_TargetFrameworkDirectories)' == '' and '$(AssemblySearchPaths)' != '' and '$(RemoveAssemblyFoldersIfNoTargetFramework)' == 'true'">
<AssemblySearchPaths>$(AssemblySearchPaths.Replace('{AssemblyFolders}', '').Split(';'))</AssemblySearchPaths>
</PropertyGroup>
Removing this constant removes the offending folders from consideration, and to be honest I cannot think of a situation where I would want an assembly to implicitly resolve to whatever version of say, Newtonsoft.Json, was hanging out in the Web Deploy or SQL Server SDK folder. That being said, I am sure there's a case out there where turning this off will cause somebody issues, so keep that in mind.
It may be worth to trigger a custom build and ticking 'clean all files in the checkout directory before the build' - you may have conflicting build tools lingering.
I found another simple solution. I manually moved
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
to the last ItemGroup section with Reference.
I have two fairly straightforward C# projects: An executable that can build as either x86 or AnyCPU, which references (via <ProjectReference>) a DLL project that only has an AnyCPU configuration. This all works as expected within Visual Studio.
I am trying to build the x86 version of the executable project (and its dependencies) from the command line, with /p:Platform="x86". This causes the build of the DLL project to fail. (Whereas /p:Platform="AnyCPU" works, presumably because it is valid for both projects.)
The full command line I am using is:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\msbuild MyProject\MyProject.csproj /t:Build /p:Configuration="Release" /p:Platform="x86"
What are my options for getting this build to work from the command line? Preferably without modifying the DLL project at all, or modifying the projects in ways that interfere with using them normally in Visual Studio.
(The ultimate goal here is a batch file that can build a clean version of the project for distribution.)
Additional info:
Both projects have "Debug" and "Release" configurations. The executable project has "x86" and "AnyCPU" available under Platform. The DLL project has only "AnyCPU" available under Platform. The "Platform target" option matches the "Platform" in all cases. (There is no "Prefer 32-bit" option, as I am on VS2010.)
The error seems to be a compilation-related error ("no unsafe code allowed") in the DLL, which -- although I am not 100% sure -- seems to be because none of the <PropertyGroup> elements in the DLL project are being matched (due to Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " etc) that would specify necessary parameters for compilation (eg AllowUnsafeBlocks and DefineConstants).
Answering my own question... First of all, MSBuild can build solution files. This does exactly what you'd expect:
msbuild MySolution.sln /p:Configuration="Release" /p:Platform="x86"
The result is an x86 executable with an AnyCPU DLL (as the solution specifies).
There are a few people out on the internet suggesting that its behaviour is not a perfect match for Visual Studio in some obscure cases. But it seems to work just fine for my purposes. (I think they were having issues with the order things get built in.)
I knew that MSBuild could build a solution file, but -- oops -- I neglected to test it on my simple reproduction case, after it failed on the more complex thing I'm working on.
The above, alone, isn't enough for a fully satisfying answer, particularly if there is a need to customise things. The way MSBuild builds solution files is to create a dummy project file, based on the solution file. This can be inspected by first setting an environment variable like so:
set MSBuildEmitSolution=true
This will emit the dummy project file next to the solution file, which can then be inspected.
I haven't completely analysed what it is doing, but it looks fairly straightforwardly like it is using the <MSBuild> task with the Projects parameter that is itself passing in the solution-specified Configuration and Platform appropriate for each project. According to the documentation it seems to be using the ones specified in AdditionalProperties. (This also seems useful to know.)
For reference, here is some relevant code extracted from the generated project file:
<Target Name="Build" Outputs="#(CollectedBuildOutput)">
<MSBuild Projects="#(ProjectReference)" BuildInParallel="True" Properties="BuildingSolutionFile=true; CurrentSolutionConfigurationContents=$(CurrentSolutionConfigurationContents); SolutionDir=$(SolutionDir); SolutionExt=$(SolutionExt); SolutionFileName=$(SolutionFileName); SolutionName=$(SolutionName); SolutionPath=$(SolutionPath)" SkipNonexistentProjects="%(ProjectReference.SkipNonexistentProjects)">
<Output TaskParameter="TargetOutputs" ItemName="CollectedBuildOutput" />
</MSBuild>
</Target>
Where #(ProjectReference) is grabbing data from:
<ItemGroup>
<ProjectReference Include="X:\Solution\MyProject\MyProject.csproj">
<ToolsVersion>
</ToolsVersion>
<SkipNonexistentProjects>False</SkipNonexistentProjects>
<AdditionalProperties>Configuration=Release; Platform=x86; VisualStudioVersion=10.0</AdditionalProperties>
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectReference>
<ProjectReference Include="X:\Solution\DLLProject\DLLProject.csproj">
<ToolsVersion>
</ToolsVersion>
<SkipNonexistentProjects>False</SkipNonexistentProjects>
<AdditionalProperties>Configuration=Release; Platform=AnyCPU; VisualStudioVersion=10.0</AdditionalProperties>
<Configuration>Release</Configuration>
<Platform>AnyCPU</Platform>
</ProjectReference>
</ItemGroup>
(Note the different AdditionalProperties.)
I updated my VS 2015 recently with the latest patch version and since then I get this error:
There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.
Output:
Restoring NuGet packages...
To prevent NuGet from restoring packages during build, open the Visual Studio Options dialog, click on the Package Manager node and uncheck 'Allow NuGet to download missing packages during build.'
1>------ Rebuild All started: Project: MoneyFox.Shared, Configuration: Debug Any CPU ------
1>C:\Users\nino\Documents\GitHub\MoneyFox.Windows\Src\MoneyFox.Shared\MoneyFox.Shared.csproj(333,3): warning MSB4011: "C:\Users\nino\Documents\GitHub\MoneyFox.Windows\Src\packages\Fody.1.29.4\build\portable-net+sl+win+wpa+wp\Fody.targets" cannot be imported again. It was already imported at "C:\Users\nino\Documents\GitHub\MoneyFox.Windows\Src\MoneyFox.Shared\MoneyFox.Shared.csproj (325,3)". This is most likely a build authoring error. This subsequent import will be ignored.
1>C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): error MSB3270: There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\\mscorlib.dll", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project.
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
The only other entry is a warning who should be the reason.
Strange is, that the project who the error occurs doesn't have the mscorlib referenced.
The error occurs in the PCL Shared Library part who is referenced by the platform specific projects. Therefore these can't build aswell.
My current build configuration is as follows:
The shared project in special:
Repository: https://github.com/NPadrutt/MoneyFox.Windows/tree/AndroidBackgroundService
I tried to repair vs but that didn't change something, as does reinstall it completly.
Funny is, that I can build it on a windows 7 pc (but get runtime error instead).
Also I can't build my master branch anymore who was buildable some days ago.
What's wrong here!?
EDIT: I created a new portable class library and unloaded all other projects.. I get the same error, also when I create a new project with just a portable class library in it. So it seems there is something pretty wrong with my current installation...
I found a solution for the problem. It seems that some of the .net profile got corrupt. But they didn't get repaired with a reinstall or repair of VS. So, therefore I deleted the Files and folders under the path C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETPortable
Then I repaired VS and it worked again..
I wouldn't think that this has to do with applying the latest patch to Visual Studio 2015.
We see this warning when we have one project that is built for x86 referencing another build for AnyCPU. This can be fixed in the Project Property page (right-click the project and click Properties). In the Build tap you can set Platform target. I would suggest that you set the configuration combo box in the top of the property window to All configurations before updating this to get it set consistently.
You can also correct this by unloading the project and editing it manually. Look for the AnyCPU property and insure that it is set in a property group without conditions or in all property groups for each configuration condition.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<OutputPath>bin\Debug\</OutputPath>
...
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<OutputPath>bin\Release\</OutputPath>
...
</PropertyGroup>
Periodically I am getting the following exception:
Unable to load DLL 'SQLite.Interop.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
I am using 1.0.82.0. version, installing it with nuget in VS2010, OS Win7 64.
Once exception starts to appear, it appears constantly - in debug and release and running application within or outside VS.
The only way to stop it is logoff and logon. The exception is not thrown and dll is loaded.
It can work for days, but then it can break again.
Has anyone seen something like this and is there a solution for it?
I know I'm late to the party but I had this issue right after I pulled down latest x86/x64 today (version 1.0.88.0). My local IIS in VS2012 runs 32bit by default and there's no easy way to switch to x64. My production server runs 64bit.
Anyway I installed the NuGet package to a DLL project and I got this error. What I had to do to get it working I had to install it to the main site project, too. Even if it doesn't touch SQLite classes at all.
My guess is that SQLite uses the entry assembly to detect which version of Interop to load.
I had this problem because a dll I was using had Sqlite as a dependency (configured in NuGet with only the Sqlite core package.). The project compiles and copies all the Sqlite dll-s except the 'SQLite.Interop.dll' (both x86 and x64 folder).
The solution was very simple: just add the System.Data.SQLite.Core package as a dependency (with NuGet) to the project you are building/running and the dll-s will be copied.
So, after adding the NuGet the deployment doesn't copy down the Interops. You can add this to your csproj file and it should fix that behavior:
<PropertyGroup>
<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
<CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
<CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
<CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
</PropertyGroup>
If you look in the source for NuGet for SQLite you can see what these are doing specifically. This allowed me to get a deploy working with ASP.Net Core.
I had this same problem when using SQLite in a WPF project whose platform target was Any CPU. I fixed it by following the following steps:
Open the project designer in Visual Studio. Details on how to do it can be found here.
Click on the Build tab.
Disable the prefer 32-bit option.
Alternatively, you could just set the platform target to x86 or x64. I think this problem is caused by the System.Data.SQLite library using the platform target to get the location of the 'SQLite.Interop.dll' file.
UPDATE:
In case the project designer cannot be reached, just open the project (*.csproj) file from a text editor and add the value <Prefer32Bit>false</Prefer32Bit> into the <PropertyGroup>...</PropertyGroup> tag.
Example code
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>[Set by Visual Studio]</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>[Set by Visual Studio]</RootNamespace>
<AssemblyName>[Set by Visual Studio]</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>[Set by Visual Studio]</FileAlignment>
<!--Add the line below to your project file. Leave everything else untouched-->
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
This is how I fixed it in my project.
It was working, and when a colleague submitted his changes, I received the "Unable to load DLL 'SQLite.Interop.dll'" exception.
Diffing the project's .csproj file, this was in the NON-WORKING version:
<ItemGroup>
<Content Include="x64\SQLite.Interop.dll" />
<Content Include="x86\SQLite.Interop.dll" />
</ItemGroup>
And this is what the WORKING version had:
<ItemGroup>
<Content Include="x64\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="x86\SQLite.Interop.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
After reverting back, I didn't receive the exception. The DLL files were dumped in the appropriate Debug\x64 (etc) folders.
When you get in this state, try performing a Rebuild-All. If this fixes the problem, you may have the same issue I had.
Some background (my understanding):
SQLite has 1 managed assembly (System.Data.SQLite.dll) and several
platform specific assemblies (SQLite.Interop.dll). When installing
SQLite with Nuget, Nuget will add the platform specific assemblies to your project
(within several folders: \x86, \x64), and configures these
dlls to "Copy Always".
Upon load, the managed assembly will search for platform
specific assemblies inside the \x86 and \x64 folders. You can see
more on that here. The exception is this managed
assembly attempting to find the relevant (SQLite.Interop.dll) inside
these folders (and failing).
My Scenario:
I have 2 projects in my solution; a WPF app, and a class library. The WPF app references the class library, and the class library references SQLite (installed via Nuget).
The issue for me was when I modify only the WPF app, VS attempts to do a partial rebuild (realizing that the dependent dll hasn't changed). Somewhere in this process, VS cleans the content of the \x86 and \x64 folders (blowing away SQLite.Interop.dll). When I do a full Rebuild-All, VS copies the folders and their contents correctly.
My Solution:
To fix this, I ended up adding a Post-Build process using xcopy to force copying the \x86 and \x64 folders from the class library to my WPF project \bin directory.
Alternatively, you could do fancier things with the build configuration / output directories.
I had the same issue running Visual Studio Express 2013. I tried several solutions mentioned here and elsewhere to no avail. I hope this fix helps others.
I fixed it by using the DeploymentItem attribute on my test class that tests the SQLite-based service.
Example:
[TestClass]
[DeploymentItem(#"x86\SQLite.Interop.dll", "x86")] // this is the key
public class LocalStoreServiceTests
{
[TestMethod]
public void SomeTestThatWasFailing_DueToThisVeryIssue()
{
// ... test code here
}
}
This causes the needed SQLite.Interop.dll to get copied to the x86 directory within the appropriate "TestResults" folder.
All is green. All is good.
Updating NuGet from Tools -> Extension and updates and reinstalling SQLite.Core with the command PM> Update-Package -reinstall System.Data.SQLite.Core fixed it for me.
old project file format
i.e. projects beginning with <Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
Add the following to your csproj on your "main"/root project
<PropertyGroup>
<ContentSQLiteInteropFiles>true</ContentSQLiteInteropFiles>
<CopySQLiteInteropFiles>false</CopySQLiteInteropFiles>
<CleanSQLiteInteropFiles>false</CleanSQLiteInteropFiles>
<CollectSQLiteInteropFiles>false</CollectSQLiteInteropFiles>
</PropertyGroup>
new SDK project file format
i.e. projects beginning with <Project Sdk="Microsoft.NET.Sdk.*">
Add PrivateAssets="none" to each ProjectReference/PackageImport in the dependency chain down to the System.Data.Sqlite PackageImport
ex:
<PackageReference Include="System.Data.SQLite.Core" Version="1.0.110" PrivateAssets="none"/>
I had a similar issue in a multiple projects solution. The SQLite.Interop.dll was necessary for one of the plugins distributed with the software using ClickOnce.
As far as debugging in visual studio everything worked fine, but the deployed version was missing the folders x86/ and x64/ containing that DLL.
The solution to have it work after deployment using ClickOnce was to create in the startup project of the solution (also the one being published) these two subfolder, copy into them the DLLs and set them as Content Copy Always.
This way the ClickOnce publishing tool automatically includes these files and folders in the manifest and deploys the software with them
There are really a lot of answers here, but mine is simple and clear with no-GAC-playing-around.
The problem was, the executable File needs a copy of the right SQLite.Interop.dll (x86 or x64) to access our Database.
Mostly architectures have layers and in my case the Data Layer has the required DLL for SQLite Connection.
So i simple put a post build script into my Data Layer Solution and everything worked fine.
TL;DR;
Set all Projects of your solution to x86 or x64 in the build options.
Add following Post-Build-Script to the Project with the SQLite nuget Package:
xcopy "$(TargetDir)x64" "$(SolutionDir)bin\Debug\" /y
Of course you have to change the script for Release Build and x86 builds.
STL;DR;
Put your SQLite.Interop.dll next to the *.exe File.
The default installation of the multi-architecture (x86, x64) version of SQLite from NuGet exhibits the behavior that you described. If you would like to load the correct version for actual architecture that the .NET runtime chose to run your application on your machine, then you can give the DLL loader a hint about where to locate the correct library as follows:
Add a declaration for the kernel32.dll function call to SetDLLDirectory() before your Program.Main():
[System.Runtime.InteropServices.DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Unicode, SetLastError = true)]
[return: System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.Bool)]
static extern bool SetDllDirectory(string lpPathName);
Then use your own method for determining the correct subdirectory to find the architecture specific version of 'SQLite.Interop.dll'. I use the following code:
[STAThread]
static void Main()
{
int wsize = IntPtr.Size;
string libdir = (wsize == 4)?"x86":"x64";
string appPath = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
SetDllDirectory(System.IO.Path.Combine(appPath, libdir));
even if it is an old post, I'd like to share the solution that I found here:
http://system.data.sqlite.org/index.html/info/54e52d4c6f
If you don't want to read all the issue, the solution is to copy the file "msvcr100.dll" (that can be found in Windows\System32 directory) in the same path as SQLite.Interop.dll.
I would advice to read the issue to understand why, and to include the file in your setup but to install it only if the error occurs, I made it an optional component selectable in the setup options.
HTH,
Formentz
I don't know why this has not been included yet, but I had to do the research and find this out for myself, so hopefully someone will find this answer and be saved the trouble. This was for a WPF app. It worked fine on my Dev box, but did not work on the computer where I was copying it and got the Unable to load DLL 'SQLite.Interop.dll' error. I ported over all of its associated directories and files, directly from my "Debug" folder to this other computer when I got the same error as the OP when I ran it. My "bin" folder that contained my DLLs had been copied to "Debug\bin" and all were included, along with my application files when I did my copying to the other computer using this path, so it was not missing any files.
Things I saw said in other answers that did not apply:
I did not use the NuGet package or need to create x86 or x64 folders that it seems that NuGet package creates. My DLLs (System.Data.SQLite and SQLite.Interop.dll, along with System.Data.SQLite.config) are in the "bin" folder in my project and were copied in manually (create "bin" folder in Solution Explorer in VS, paste DLLs into this folder in Windows Explorer, use Add > Existing Item to bring files into VS folder/project). Then I reference them as Referenced Assemblies in my project using that location ("References" > "Add Reference", and browse to one, rinse, repeat for the rest). This ensures my project knows exactly where they are.
I did not need to reference any SQLite DLL file in my app.config or even touch my MyProject.csproj file.
I did not even need to specify a particular processor! My project's build is for "Any CPU", even though I have only mixed or 64-bit DLLs and will only be running on Windows 7+, which are 64-bit OSes. (no x86-only/32-bit solely DLLs)
I was already specifying them as "Content" and "copy if newer" for these DLLs when I experienced the OP's error.
What I found was this, from https://system.data.sqlite.org/index.html/doc/trunk/www/faq.wiki#q20 :
(11) Why do I get a DllNotFoundException (for "sqlite3.dll" or "SQLite.Interop.dll") when trying to run my application?
Either the named dynamic link library (DLL) cannot be located or it cannot be loaded due to missing dependencies. Make sure the named dynamic link library is located in the application directory or a directory along the system PATH and try again. Also, be sure the necessary Visual C++ runtime redistributable has been installed unless you are using a dynamic link library that was built statically linked to it.
Emphasis mine on that bolded part inside the paragraph. The target computer was fresh and had no programs loaded except .NET 4.0. Once I installed C++, it was able to complete the commands to SQLite. This should have been one of the first FAQs and part of the pre-requisities, but it was buried at #11. My development computer already had it loaded because it came with Visual Studio, so that's why it worked, there.
Download:
Visual C++ Redistributable for Visual Studio 2015:
https://www.microsoft.com/en-us/download/details.aspx?id=48145
Update 3 (cumulative update):
https://www.microsoft.com/en-us/download/details.aspx?id=53587
As the SQLite wiki says, your application deployment must be:
So you need to follow the rules. Find dll that matches your target platform and put it in location, describes in the picture. Dlls can be found in YourSolution/packages/System.Data.SQLite.Core.%version%/.
I had problems with application deployment, so I just added right SQLite.Interop.dll into my project, the added x86 folder to AppplicationFolder in setup project and added file references to dll.
I had the same issue. Please follow these steps:
Make sure you have installed System.Data.SQLite.Core package by
SQLite Development Team from NuGet.
Go to project solution and try to locate build folder inside packages folder
Check your project framework and pick the desired SQLite.Interop.dll and place it in your debug/release folder
Reference
Copy "SQLite.Interop.dll" files for both x86 and x64 in debug folder. these files should copy into "x86" and "x64 folders in debug folder.
You could also get this error if you are trying to run a 32 bit dll, in a 64 bit project.
I got this when I have placed the same file(SQLite.Interop.dll in 32 bit version) in both the x86 and x64 folder.
If you download correct binary for SQLite then copy SQLite.Interop.dll into your Release or Debug folder according to your project build option.
I have started using Costura.Fody to package (.net) assemblies and embed and preload native dlls. This also helps later, with distribution as you can send one file.
Install Costura Fody from Nuget.
In your C# project create a folder called costrua32. In there add any native dlls you which C# to load.
Once you have added them to this folder. Click on the properties window and change build action to "Embedded Resource"
Finally you need to amend the XML file called FodyWeavers.xml as follows. Here I am specifying load the sql dll first. (note you drop the .dll)
Weavers
Costura
PreloadOrder
SQLite.Interop
tbb_debug
tbb
/PreloadOrder>
/Costura
/Weavers
The advantage of this is that you do not have to write any pre or post build events, and the end product is totally encapsulated in to one larger file.
Also added the dll to the test project (through Nuget Manager) and it fixed it.
Could there be contention for the assembly? Check to see whether there's another application with a file lock on the DLL.
If this is the reason, it should be easy to use a tool like Sysinternal's Process Explorer to discover the offending program.
HTH,
Clay
I had this problem because Visual C++ 2010 redistributable no installed in my PC.if you have not already installed Visual c++ 2010 redistributable Download and install this(check x86 or 64 dll).
I got the same problem. However, finally, I can fix it. Currently, I use Visual Studio 2013 Community Edition. I just use Add->Existing Item... and browse to where the SQLite.Data.SQLite files are in (my case is 'C:\Program Files (x86)\System.Data.SQLite\2013\bin'). Please don't forget to change type of what you will include to Assembly Files (*.dll; *.pdb). Choose 'SQLite.Interop.dll' in that folder. From there and then, I can continue without any problems at all. Good luck to you all. ^_^
P.S. I create web form application. I haven't tried in window form application or others yet.
Try to set the platform target to x86 or x64 (and not Any CPU) before you build:
Project->Properties->Build->Platform target in Visual Studio.
Copy SQLite.Interop.dll in project directory.
src\
project\
bin\ <-- Past in bin
x64\
SQLite.Interop.dll <-- Copy this if 64
x86\
SQLite.Interop.dll <-- Copy this if 32
I've struggled with this for a long time, and, occasionally, I found that the test setting is incorrect. See this image:
I just uncheck the test setting, and the issue disappears. Otherwise, the exception will occurs.
Hopefully, this will help someone.
Not sure it's the root cause.
My application is a web application (ASP.NET MVC) and I had to change the application pool to run under LocalSystem instead of ApplicationPoolIdentity. To do this:
Open IIS Manager
Find the Application Pool your site is running under.
Click Advanced Settings from the actions
Change Identity to LocalSystem
I have no idea why this fixes the issue.
My situation was a little unique. I was running an application inside a docker container and kept getting the following error
System.DllNotFoundException : Unable to load shared library 'SQLite.Interop.dll' or one of its dependencies. In order to help diagnose loading problems, consider setting the LD_DEBUG environment variable: libSQLite.Interop.dll: cannot open shared object file: No such file or directory
So I set LD_DEBUG=libs to find out what folders System.Data.SQLite.dll was looking in to find SQLite.Interop.dll.
You can find info on setting LD_DEBUG here: http://www.bnikolic.co.uk/blog/linux-ld-debug.html
Once I did that I realized that SQLite.Interop.dll was being found just fine. The DLL that wasn't being found was libSQLite.Interop.dll. I should have read the entire error message.
Hours of Googling later I found this guide on how to compile the missing DLL from the SQLite source code.
Note that the file that was actually missing was libSQLite.Interop.dll.so
Anyway when you compile the source code you get libSQLite.Interop.so which you need to rename to libSQLite.Interop.dll.so and put it in the directory that it's looking in which you can find by setting LD_DEBUG.
For me the directory that System.Data.SQLite.dll was looking in was /usr/lib/x86_64-linux-gnu/
Upgrading to Visual Studio 2019 ver. 16.10 caused the issue for me, where msbuild reported the following for the System.Data.SQLite.Core-package:
CopySQLiteInteropFiles:
Skipping target "CopySQLiteInteropFiles" because it has no outputs.
https://github.com/dotnet/msbuild/issues/6493
Microsoft says the bug has been fixed with ver. 16.10.4. Now just have to wait for AppVeyor to update their Visual Studio Images (Until then one can use Previous Visual Studio 2019).
Now AppVeyor is using broken dotnet-build-engine for both current and previous Visual Studio 2019-image. Now one have to explicit install dotnet sdk ver. 5.0.302:
Invoke-WebRequest -Uri 'https://dot.net/v1/dotnet-install.ps1' -UseBasicParsing -OutFile "$env:temp/dotnet-install.ps1"; & $env:temp\dotnet-install.ps1 -Architecture x64 -Version 5.0.302 -InstallDir "$env:ProgramFiles\dotnet"