So I have a solution with 3 projects. One of the projects is built as a class library and is referencing a third party DLL. When I am building the solution everything is just fine. However, when I run the program and call a method inside my class library I get a "File not found" exception for the referenced third party DLL.
When I look in the output folder I can see the DLL.
I also tried to load it using:
Assembly.LoadFile("absolutePathToFileInOutputFolder")
Still getting the same exception. But if I use the path to another copy of the DLL it works.
So what could be the reason for this behaviour? Can it be that one of my projects are locking the DLL for the other projects?
This is a recurrent issue once in a while in Visual Studio. Usually it corrects itself setting the reference to said DLL on the Properties Window with CopyToLocal = True.
Related
As the title says, I want to consume all of PDFSharp's source code into my own project. But let me explain why I came to this scenario, so if there is something else I can do, maybe there are other options.
Goal: Compile my project into a single .exe file to use. No installers.
Problem: It uses PDFSharp.dll which is causing me issues.
What I am trying to do, is use ILMerge to create the .exe. I've used this successfully in the past for other projects.
The issue I think is that ILMerge is requiring references to other assemblies that PDFSharp uses. The first being Microsoft.ApplicationInsights. So to by-pass this, I installed Microsoft.ApplicationInsights into my project via Nuget. Then removed the actual reference from the project, but referenced the library in my ILMerge command as below:
/lib:"C:\<path to assembly>\Microsoft.ApplicationInsights.2.16.0\lib\net46"
This actually worked. Except, now it asked for another library and I get this error:
Unresolved assembly reference not allowed: GdPicture.NET.11.
This looks like a paid library, perhaps downloading the trial may get me past this. I didn't try yet. I switched gears as I felt I may be trying to reference an endless amount of assemblies.
I then tried to get the PDFSharp source code and I found that version 1.32 here:
https://sourceforge.net/projects/pdfsharp/files/pdfsharp/PDFsharp%201.32/
I added a reference to this project within my solution file, so now I have a solution with 2 projects. Great.
I then I tried to link source files into my project. How to do that is here:
https://jeremybytes.blogspot.com/2019/07/linking-files-in-visual-studio.html#:~:text=To%20link%20files%2C%20use%20the,CLICK%20THE%20%22Add%22%20BUTTON.
This seems to work, but every file I add requires another file, which references another file etc. It seemed endless. So that led me to the idea of just consuming the entire source code into my project and I haven't seen a good way to do that yet. I can't add a reference to the project as it just references the compiled dll which again, iLMerge can't combine.
I've also tried updating the tag within the .csproj file of PDFSharp to "module" to create a .netmodule file. This creates the file in the obj directory but throws an error:
\PDFsharp\code\PdfSharp\obj\Release\PdfSharp.netmodule' is not an assembly
Any help is appreciated. thanks.
UPDATE: I reversed everything and added the PdfSharp reference - back to where I was and changed my project to module and built which created a .netmodule file. Then used the assembly linker to create a .exe from that file. That worked using this command from VS Dev prompt.
al MyModule.netmodule /target:exe /out:MyProgram.exe /main:MyNamespace.MyClass.Main
This created the .exe, but when run without any other supporting files produces a file not found error:
System.IO.FileNotFoundException: Could not load file or assembly 'MyModule.netmodule' or one of its dependencies. The system cannot find the file specified.
Which is interesting since the module should be inside the exe right?
I have this working now, so I just wanted to place my results here since it is already posted.
My initial problem was that I mistakenly thought the PDFSharp.dll was causing the issue, but it was actually another group of 3rd Party dlls I was referencing.
I tried for hours to get iLMerge to work with the only success being it would kick out a single .exe file but it would have runtime errors.
Errors that I encountered:
Error: Unresolved assembly reference not allowed: Custom.Assembly.
Solution: Reference the assembly if possible. If you have many, you can reference a folder with the /lib:"C:\folderpath" switch.
Error: Unresolved assembly reference not allowed: ADotNetFramework.dll.
Solution: You can reference the desired .Net Framework path where iLMerge will search for missing references. Example: /targetplatform:"v4,C:<Path To Framework>.NETFramework\v4.8"
Error: The assembly 'xyz.dll' was not merged in correctly. It is still listed as an external reference in the target assembly.
Solution: You can get past this error with the /closed switch. However, I don't think I should even have gotten this error because 'xyz.dll' was a referenced dll to be combined.
Also - use the /log switch, it is extremely helpful in seeing exactly what iLMerge is doing and figuring out your issue. Example: /log:mylog.txt
This allowed me to see that iLMerge was finding duplicate namespaces, in the 3rd Party assemblies and automatically renaming them. Here is an example from my log:
Merging assembly 'My.Assembly.Name' into target assembly.
Duplicate type name: modifying name of the type '<>f__AnonymousType02' (from assembly 'My.Assembly.Name') to 'My.Assembly.Name.<>f__AnonymousType02'
Duplicate type name: modifying name of the type '<>f__AnonymousType12' (from assembly 'My.Assembly.Name') to 'My.Assembly.Name.<>f__AnonymousType12'
Duplicate type name: modifying name of the type '' (from assembly 'My.Assembly.Name') to 'My.Assembly.Name.
Finally - the solution that I found was not to use iLMerge. I found this Answer: https://stackoverflow.com/a/40786196/2596309
which used Costura.Fody
I installed the nuget package with:
Install-Package Costura.Fody -Version 4.1.0
Cleaned and built my solution and it created a single .exe file that I tested and it worked. Literally, I put 3 days of work into this and the solution took 3 minutes...
At the moment of creating a project of type "Library of Classes, usually one can generate a dll when compiling, but how could I generate a dll without losing others that I already have included?
I explain with an example: It turns out that Nuget downloaded an S22.Imap dll with the one I worked with, later I generated the dll in the traditional way that I explained in the beginning, but when I wanted to work with dll in another computer, I got errors that were not I found functions that contained the S22.IMAP dll. So to solve this problem, I had to copy the dll of my project, S22.IMAP in an additional way in a specific path of the other computer.
My question is:
How could you generate a dll that includes the ones included in the project you were working with?
All the referred 3rd party dlls (S22.Imap.dll in your example) will be copied to the output folder together with your own dll file (let's say a.dll) when you build your project. That means you should always copy them together (S22 + a.dll) to the place you want to refer them, on another computer/folder/place.
If you really want to make them only one file (although it is not recommended), you can set the S22 one as some "nested resource". Then you will get only one a.dll file and the S22 one is inside the a.dll. See below page for some reference:
Embedding one dll inside another as an embedded resource and then calling it from my code
AND, ILMerge is some tool that can help you do so.
In general, you don't. A DLL is a dynamic linked library, and you would normally only combine static libraries during a build. Here is an answer on the difference between static and dynamic linking.
Typically you would include all the DLLs you need in the installer package. If you use Visual Studio to create the installer, it can detect the dependencies for you. When you run the installer, all of the necessary DLLs are deployed. Nearly all commercial .NET software follows this pattern.
It is possible to merge an assembly into another assembly using a tool called ILMerge. This would be a very unusual thing to do, and could cause issues with intellectual property and code signing, so it is not recommended.
I created a managed VC++ class library, and now I created a new C# console application. I added the DLL from the class library as a reference. Now, when I try to run my program from VS, VS complains that it cannot find the DLL. When I check the output folder bin\Debug, however, the DLL is there.
Is there anything I forgot to configure?
The correct answer was in Hans passant's comment: The DLL which could not be loaded referenced another DLL which was not present in the output directory. That's why I got the exception.
I now added a post-build step which copies the DLL to the output directory after a successful build, and voilĂ , it works.
We use a 3rd party mixed mode assembly that interfaces with a printer device.
In one of our applications, the assembly functions correctly.
In another application, it was generating the following exception:
Mixed mode assembly is built against version 'v2.0.50727' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.
After doing some research, I discovered that I could add the following to the app.config file to resolve this problem:
<startup useLegacyV2RuntimeActivationPolicy="true">
(The application that works already had this setting in its app.config)
Although this did resolve the "Mixed mode assembly" issue, now I'm seeing a somewhat different problem:
External component has thrown an exception
The strange thing is that I have one application which works correctly and another application which does not. They both call the third party assembly via the same code (which is another one of our assemblies).
I tried creating a very simple test app which calls the third party assembly using the same code path, and it also fails with the "External component has thrown an exception" error.
I've compared the app.config files for all of the applications and they are essentially the same, and I've double checked that all of the build settings are the same for each. Both projects target .NET 4.0 and X86.
There is obviously something different about the two applications but I'm at a loss to identify what it is.
Development environment is Visual Studio 2010.
Does anyone have any suggestions on what other areas I could investigate?
#tsells was right: there was a missing dependency
The third party assembly in question depended on another DLL that was present in the first applications bin folder.
I copied all of the files from the working application's bin folder to the non-working application's bin folder, and it resolved the problem.
From there it was just a matter of deducing which DLL was missing and including it in the second applications project.
When there are dependencies missing, you can use tools like CheckAsm for managed and Dependency Walker for unmanaged libraries to check for dependencies.
My UserControl references a C++/CLI wrapper to an unmanaged C++ dll. When I try to add the UserControl to a form, I get a Visual Studio error, which says "Failed to create component 'userControl'", giving a System.IO.FileNotFoundException as the cause.
From what I've been able to determine, the problem stems from visual studio not copying the C++/CLI wrapper assembly's unmanaged dependencies. If I put the unmanaged dependencies on the system PATH, everything works fine.
Is there a better way of doing this?
The easiest thing to do would be to include the actual .dll in your project, mark its build action as "Content", then set the Copy to Output Directory to "Always". This should get the .dll into your output directory so that your application can run, and just including the file in the project should put it in the project directory so that the designer can find it.
Be sure that your setup project includes a project output for the Content files from that project as well.
Edit
If those don't work, you can also edit the reference paths of the project itself (in the project properties), though I am not certain that this will affect the designer. If that doesn't then your only real option is to have the .dll in one of the system path directories.
Old thread, but submitting my solution since I just encountered the issue and found this question during the process.
Basically I just made the native DLLs to be delay loaded in my wrapper C++/CLI library. Since the C++/CLI part of the wrapper contains the interface specs used by Visual Studio and the framework, the native DLL is never needed or loaded. I answered it with a little more details in this question too:
https://stackoverflow.com/a/15481687/34440