I've been going circles on this one for over a day now. I have a WPF project that is making use of sqlite-net-pcl.
I'm ready to package this project up into an MSI for distribution (x64). The first hitch was that I need to directly add the nuget for the dependency (SQLitePCLRaw.bundle_green). I've come across this before when a nuget package contains content files that need to find their way into the final release. Smooth sailing.
At this point, the bin/x64/release is good and runs fine. However, when I build an installer and run the installed version I get the following exception:
System.BadImageFormatException: Could not load file or assembly 'System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. Reference assemblies should not be loaded for execution. They can only be loaded in the Reflection-only loader context. (Exception from HRESULT: 0x80131058) ---> System.BadImageFormatException: Cannot load a reference assembly for execution.
Doing a file compare between my release folder and the application install folder I find the following:
Binary Difference: System.Buffers.dll
Binary Difference: System.Numerics.Vectors.dll
Binary Difference: System.Runtime.CompilerServices.Unsafe.dll
Installer Only: netstandard.dll
Installer Only: System.Diagnostics.Tracing.dll
Installer Only: System.IO.Compression.dll
Installer Only: System.IO.Compression.FileSystem.dll
Installer Only: System.Net.Http.dll
After inspecting further and digging in to the DLLs, I find if I overwrite System.Runtime.CompilerServices.Unsafe.dll with the binary from my release folder everything works.
Digging in even further and inspecting the installer version of CompilerServices.Unsafe I realize that the installer is grabbing the dotnet core version of the DLL.
I've isolated this down to a single console app with a fresh installer project and only adding the content and output to the installer.
Why is the installer insisting that the dependency is a dotnet core version?
I'd like to find a real solution, but in the meantime I found some confirmation and a dirty workaround in this thread: https://developercommunity.visualstudio.com/content/problem/810090/visual-studio-installer-projects-extensions-incorr.html
Workaround option 1: In addition to adding the “Primary Output” of the project containing the package reference also add “Locally-Copied Items” for that project. This will result in the lib version of the assembly overwriting the ref version, giving you the behavior you want. However, you’ll also get a warning about the duplicate file being added, since as I said the lib version will be overwriting the ref version. This also could bring in additional files like xml doc files that should have no impact at runtime but may increase the size of the installer. These can also be individually excluded from the setup project.
I created a setup project using Microsoft Visual Studio Installer Projects (0.9.3, this is latest for Visual Studio 2019). After setup is executed it installs Nuget package assemblies that are different from the assemblies generated during build.
Why is it doing that and how can I make it to chose assemblies consistent with build assemblies?
My application is for 4.7.2 framework. Typical example is System.ValueTuple.dll (4.0.2)
Build retrieves assembly from:
C:\Users\.nuget\packages\system.valuetuple\4.5.0\lib\net47\System.ValueTuple.dll
Install retrieves assembly from:
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETFramework\v4.7.2\Facades\System.ValueTuple.dll
While install based on 4.0.2 creates a concern but works, when I upgrade nuget package to version 4.6 (and assembly to 4.0.3) install switches to using assembly C:\Users\vgdev.nuget\packages\system.valuetuple\4.5.0\ref\net47\System.ValueTuple.dll
If you look closer, you will notice path above has \ref folder and it contains "reference" assembly. Reference assemblies are not meant to be installed and cause errors BadImageformatException.
The build after Nuget package upgrade continues to pull packages from the correct \lib folder and application works fine. So what I want to do is to make installer work consistently with build. Any advice?
Install retrieves assembly from: C:\Program Files (x86)\Reference
Assemblies\Microsoft\Framework.NETFramework\v4.7.2\Facades\System.ValueTuple.dll
Which way do you reference that package? I can only reproduce this issue when I add reference manually.(Right-click project=>Add reference=>Browse...) If you're doing so, please remove that reference, and add that reference back by Nuget Package Manager UI.
My application is for 4.7.2 framework. Typical example is
System.ValueTuple.dll (4.0.2). When I upgrade nuget package to version 4.6 (and assembly to 4.0.3)
I can only find it with latest 4.5.0 here. And I think it contains the assembly version 4.0.3 instead of 4.0.2.
(I guess something corrupts the process when VS recognize your assembly version cause in most machines it displays 4.0.3 while in one machine, it displays 4.0.2, quite strange...)
The build after Nuget package upgrade continues to pull packages from
the correct \lib folder and application works fine. So what I want to
do is to make installer work consistently with build. Any advice?
Cause of the issue:
This strange behavior may have something to do with Setup project. I can reproduce same situation and I found this issue only occurs when I use PackageReference format to manage nuget packages in my application.(.net 4.7.2)
PackageReference format is the new nuget package manage format after VS2017. I'm not sure if the Setup project fully support for it.
Here're two suggestions which may help:
1.I found this issue only occurs when using PackageReference format. So you can try using Packages.config format in your application. And I've checked the setup project can recognize this format well.
Uninstall all PackageReference format packages, and go Tools=>Nuget Packages Manager=>Nuget Package Manager to set the Allow format selection... to true.
Clean all nuget cache and click ok. After that delete bin and obj folders, then restart VS to add those packages back using Packages.config format.
2.If you continue to use PackageReference format. Try excluding the assembly from ref folder, and manually add that from lib folder by Add=>Assembly=>Browse.
Note: Since Setup project may not fully support packageReference format projects, actually I think #1 could be more suitable for your situation. And you can create a new simple project with packages.config format to check if the issue can be resolved by Packages.config format. Hope it helps :)
It seems that the root cause of the problem is the usage of the BuiltProjectOutputGroupDependencies target by visual studio setup projects instead of the ReferenceCopyLocalPathsOutputGroup target (see PackageReferences put ref instead of lib assemblies in the output group used by VS installer projects).
The proposed workaround is to overwrite the BuiltProjectOutputGroupDependencies target at the end in the project file of your main project:
<Target
Name="BuiltProjectOutputGroupDependencies"
DependsOnTargets="$(BuiltProjectOutputGroupDependenciesDependsOn)"
Returns="#(BuiltProjectOutputGroupDependency)">
<ItemGroup>
<BuiltProjectOutputGroupDependency Include="#(ReferenceCopyLocalPaths->'%(FullPath)');
#(ReferenceDependencyPaths->'%(FullPath)');
#(NativeReferenceFile->'%(FullPath)');
#(_DeploymentLooseManifestFile->'%(FullPath)');
#(ResolvedIsolatedComModules->'%(FullPath)');
#(ReferenceComWrappersToCopyLocal->'%(FullPath)')"/>
</ItemGroup>
</Target>
I'm using visual studio 2015, Microsoft Visual Studio 2015 Installer. I'm creating the sample project for demonstrate my issue.
Step1: I'm creating the SampleSetUpProject in wpf Application.
Step2: Creating the ClassLibrary1 Project and adding the itextsharp reference in that project.
Step3: I'm creating the Setup1 Project in that application. In Application Folder adding Project output, the dependency DLL itextsharp not added in the Application folder. How to added the dependency dll adding project output?
Step4 : In application output directory my DLL's are there. But adding project output it's not added. If any possibilities are there for adding the Dependency dll's adding Project output?
Image for Adding Project output.Image link
A setup can't know every one of your dependencies - for example there is nothing about a COM call that identifies a required Dll because the code references a GUID - so they need to be added manually. As your "Add" dialog shows, just add the Dlls (add file) and so on, to install to whichever location they are needed in. And another issue is that not all dependencies will be in the Application Directory - some (such as a shared COM Dll) need to be installed and registered in a common location. So some dependencies might be in Common Files, the GAC and so on.
I'm not a a very experienced Windows developer, so I hope this all makes sense.
I created a Managed Assembly DLL using Visual Studio 2010. The DLL (Plip.dll) contains a C++ class that is using System.IO.SerialPort class to do some simple communication over a serial port.
In a second Visual Studio project I created a simple GUI that uses the class found in Plip.dll. In my GUI project I have the line : #using "Plip.dll" . In the Project Properties I set the 'Resolve #using References' value to the correct location of Plip.dll. The GUI builds just fine. If I copy the GUI.exe and Plip.dll to the same folder, the GUI runs just fine on my computer.
The problem I am having is that when I copy both files to a second computer, I cannot get the GUI executable to run. I get the following error : "System.IO.FileNotFoundException. Could not load file or assembly "Plip.dll" Vesion=.... ". I get this error even though both the exe and dll are located in the same folder.
Any suggestions on how to resolve this issue? Is there some option I need to set in my GUI project to load the DLL correctly at run time?
I suppose the problem is not the Plip.dll, but it's dependencies.
Use Dependency Walker on the second computer to see if it needs any other dll's (they might be installed in System folder or in %PATH% on your development computer, but not on the other).
If this second computer doesn't have Visual Studio installed, you are probably missing Microsoft Visual C++ 2010 Redistributable Package (you need to install it on the other computer)
Also make sure that you compile in Release because debug builds need debug dependencies.
I found the answer to this problem to be much simpler than Dependency Walker (but admittedly, that was fun to look at).
In my case, the issue was a mis-match between the .DotNet versions in the DLL and with the application's .net version. This was caused by building the "class library" using .DotNet 6.0 (dot net core?).
Instead, the entire class needed to be re-built using "Class Library (.NET Framework)"
enter image description here
I wrote an article on this problem.
https://keyliner.blogspot.com/2022/09/visual-studio-c-linked-dll-exception.html
We have several external DLL files being referenced in our Web Application Project. We have a deployment project for installing on the hosting servers. When we were using .NET 3.5 and Visual Studio 2008 the DLL files were being copied to the bin folder. Since we have upgraded to .NET 4 and Visual Studio 2010 this no longer happens, and we are getting server errors since the references cannot be found.
CopyLocal is set to true, and I cannot find anything inside the web.config which suggests this is being set elsewhere.
There is a bug in Visual Studio 2010. By default the XML in the solution file looks like this:
<Reference Include="DevExpress.SpellChecker.v11.1.Core,
Version=11.1.5.0,
Culture=neutral,
PublicKeyToken=b88d1754d700e49a,
processorArchitecture=MSIL">
<HintPath>..\References\DevExpress.SpellChecker.v11.1.Core.dll</HintPath>
</Reference>
Whereas MSBuild is expecting this below, so that the DLL file will be included in the deployment:
<Reference Include="DevExpress.SpellChecker.v11.1.Core,
Version=11.1.5.0,
Culture=neutral,
PublicKeyToken=b88d1754d700e49a,
processorArchitecture=MSIL">
<HintPath>..\References\DevExpress.SpellChecker.v11.1.Core.dll</HintPath>
<Private>True</Private>
</Reference>
The trick is to set Copy Local to False, save the project and then reset it to True - save again. This includes the Private node correctly, which MSBuild respects.
It appears that the default for no included private node (Copy Local) in Visual Studio 2010 is True, while MSBuild reads that missing node as False.
I was getting the same problem and rather than add a "BeforeBuild" step I created a test that simply did this
[TestMethod]
public void ReferenceAssemblyThatDoesNotCopyToBuildFolder()
{
Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler referenceThisButDoNotUseIt = null;
}
And that fixed the error The type 'Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler...' cannot be resolved
Something weird had happened to my deployment project. When I saw it had no detected dependencies, I removed the primary output and re-added it.
The dependencies are now showing up and being placed in the bin folder when installed.
I was getting exactly the same issue. We have a Visual Studio 2008 project which references the EnterpriseLibrary. When we run our integrated build using TFS and our Web deployment project, all the DLL files are copied over. When we upgraded to Visual Studio 2010, TFS 2010 and WDP 2010, some of the DLL file's were missing. Strangely, this only occurs to some DLL files and not others.
For example, we get the Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.dll copied in both cases, but not the Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.dll.
As a workaround I copied the files accross using a "BeforeBuild" step.
It now seems to build OK.
I just had the same issue and wanted to share what I found as it might help someone:
The reason in my case was that the assembly was installed in the GAC during an installation of some third-party application.
If the DLL file is in the GAC, the compiler won't bother to copy it to the destination folder, unless you specifically mark it for "copy local" using the "Private" node in the project file as mentioned by Junto.
The thing is that if you don't add that node, and you develop on one machine and build on a different one, and the DLL file is only in the GAC of the build machine, the default behavior without the private node will cause the file to be copied correctly on the development machine, but not on the build machine.
The bigger problem is if the DLL file is not referenced directly, but the project references a second project that in turn references the DLL file. In that case, you cannot mark the DLL file to be "copy local" in the project, as it is not referenced by it. So if the DLL file exists in the GAC - it won't get copied to your output folder.
Possible solutions to this case are:
Uninstall the DLL file from the GAC
Add a direct reference to the DLL file in the end project(s)
Re-sign the DLL file with a new strong name, which will differentiate it from the DLL file in the GAC.
I am not sure how it was set up in Visual Studio 2008, but I am almost positive that you might have been using the Post-Build event command line. In there you can tell to copy the DLL files you need for deployment. An example is given below:
mkdir $(SolutionDir)\Deployment
copy "$(SolutionDir)Your_Library_Name\Your_Dll_ForDeployement.dll"
$(SolutionDir)\Deployment\
I didn't meet the same problem but similar. I had WPF main project and referenced project where the referenced did not copy. I found that in my case the main project was set for NET 4.0 Client Profile and the referenced for NET 3.5. When I set the main project to 3.5 the compiled dll of the referenced project started to copy.
(I don't know why because I solved it by practice)
I too ran into a similar issue where referenced dlls were not copied into the bin in published folder. I was using a TFS checked out copy that didn't include the bin folder into the application.
-> So just included the bin folder.
-> Built the referenced applications
-> Published the website project
Now I see all the referenced dlls in bin in the published folder
I had a similar issue with VS 2012 Express. I used Tesseract libraries in my project. Everything worked well until I used this project in a solution where were more than one project. Problem was that some DLLs (liblept168.dll, libtesseract302.dll) that are normally placed in folders bin/debug/x86 or bin/debug/x64 were copied only when I rebuilt whole solution.
Changing a single line and building it again caused that the DLLs were deleted and not copied back.
I solved this issue by adding a reference of the project that creates missing DLLs to the startup project.
rzen and others, thanks - your comments led to a solution for us.
We have a project that targets version 10 of the Microsoft.ReportViewer.Common.dll and Microsoft.ReportViewer.WebForms.dll assemblies (separate "libs" folder we created at the 'src' level). But when we did a build, the output included version 12, which was recently installed on the build server.
Using comments here, we ensured that 'Copy Local' was set to True and that the flag was set in the project file. However, it was still deploying version 12. So what we found that did the trick was ensuring that the 'Specific Version' property was also set on the two references. Voila, version 10 of each file is now being deployed!
There was much rejoicing.
JH
If your project does not directly load the library, it won't always be deployed, even if it is referenced explicitly! I got confused because I could see it in a local Bin directory but not when deployed. The dll in the Bin directory was an old file that wasn't removed during Clean which is why I was confused.
A full clean and rebuild and it wasn't in my local Bin folder either which showed me the problem (I only use it in web.config). I then referenced the dll file itself in the project and set it to copy to output to make sure it gets deployed.
We can use the <Private>False</Private> to not to copy the referenced DLL files to the bin directory. This is useful when we are building applications in a separate TFS build server where we need to build the application and not to copy the DLL files to the bin directory.
Check the framework of the project in which the DLL file has been referenced. The framework should be .NET 4.0. Please correct it if the framework is Client Profile.
Adding the parameter
/deployonbuild=false
to the msbuild command line fixed the issue.
Got a similar issue when upgrading old WebSites into WebApplications.
The "Clean Solution" command would wipe out all external DLL files I purposely left in my bin folders.
Besides, it was not possible to bring those DLL back automatically simply by referencing them all, since many of them have the same file name (it happens when you work with many language specific resources)
Like stevie_c did, I took advantage of the Pre-Build command, but made it simpler:
I just used a xcopy command in the Pre-Build operation of the WebApplication project's properties. This way I could bring over the necessary external DLL files just before the build would start.