Preface: I know basically nothing about C#.
I've added a dll to my project. I have no build errors, but when I try to run, I get an error that says it can't find the dll. I've tried copying it to the output directories too. To no avail.
Any idea what could be happening?
Specific Error:
System.IO.FileNotFoundException was unhandled Message=Could not load
file or assembly 'controllib_clr.dll' or one of its dependencies. The
specified module could not be found. Source=controllib_demo_cs...
I'll be happy to add more information if need be. :) I just don't know what info would be beneficial given my (very) limited knowledge.
It looks like it is not able to find/load some dependencies dlls I will use DependencyWalker to figure out what it is missing http://www.dependencywalker.com/
Is it a managed (.NET) or an unmanaged (native) DLL? I'm assuming unmanaged.
FileNotFoundException is commonly thrown when missing a dependency. The DLL you are loading might require any number of other DLLs on load. In most cases it won't tell you which file it needs. You have to refer to the documentation for that DLL.
If it exists, in your output folder, then most likely its one of its dependencies that is missing. You can fix this by adding its dependencies as references in your project.
if it doesn't exist in your output, then, check that "Copy Local" is set in the properties of the reference.
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...
I get following error message:
Unable to load DLL 'Xeneth.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
Although the Xeneth.dll has been added under the references I get this error message on this codeline:
XCHANDLE = (uint)DllImports.XC_OpenCamera(CameraName, StatusCallback, IntPtr.Zero);
thanks in advance for the help..!
That error code is a COM error wrapping the Win32 error code ERROR_MOD_NOT_FOUND. This means that either Xeneth.dll or one of its dependencies cannot be found on the DLL search path.
You should consult the documentation for this library to work out where it must be deployed. Usually, and most sensibly, unmanaged DLLs should be placed in the same directory as the executable file. Doing so ensures that they are located.
If doing that does not help, then you may need to deal with missing dependencies. Again check the documentation. Do you need to install an MSVC runtime on which this DLL depends?
If all this fails then you might try using a tool like Dependency Walker, and use its profiling mode to try to work out what is missing. However, I do suggest that you start with the library documentation first. It's always best to follow and understand the instructions.
I have to create objects for a particular class at runtime, the classes should be configured in the app settings of the web.config file, using Reflection.
The problem is, I am not able the Load the assembly. Since the classes are in the referenced dlls. I am not able to get the actual path of the referenced dll.
I Have tried Path, CodeBase, Current Directory. Can someone help me??
If the assembly is referenced by the project, you don't need to load it. You can get it by getting the Type of a class which is in that particular assembly.
In general, doing Late-Binding on your own, isn't the best of an idea. We had some issues with that at our project and it's quite a lot of work to do it right. You could instead use some of the many different IoC-Containers, which will find the assembly and also the class for you.
EDIT:
I was maybe a bit confused, that I didn't think of it earlier. You can simply load an Assembly by it's name. Than it should find the assembly in all the referenced paths or the GAC.
Further information can be found at MSDN
I got "Referenced assembly 'xxxxxxxxxx.GPUImage' does not have a strong name error" and according to How to fix "Referenced assembly does not have a strong name" error, I have corrected the issue. I have added the correct referencing also. (I have this problem with two other third-party assemblies and after signing them they work properly.)
But after I sign, it gives a new error which was not been given earlier. It is as follows.
Error 2 The type 'xxxxxxxxxx.GPUImage.ImageFilter' is defined in an assembly
that is not referenced. You must add a reference to assembly 'xxxxxxxxxx.GPUImage',
Version=2.0.0.0, Culture=neutral, 'PublicKeyToken=null'.
What is the reason for this? Can a .dll consist with an unassigned .dll inside the signed one?
As mentioned by #eric, I run fusion log and the following is the log file.
Search for all occurrences of the unsigned assembly on your hard disk, and delete them - keep just the signed version. Then do a complete rebuild. It'll either work, or you'll find who's referencing the old assembly.
Learn and use Process Monitor, and then you can see from where your process tries to load the assemblies,
http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx
After knowing all the locations, go ahead and remove those unsigned versions. Usually they might be cached somewhere by your unit testing suite or something else. By deleting them, you should be able to resolve the problem.
Some assembly in your solution is still referencing an unsigned version of the assembly that defines GPUImage.ImageFilter. You get that from PublicKeyToken=null.
Try looking at how loading is resolving using the Fusion Log Viewer. It should tell you which assembly is trying to reference the unsigned one.
After reading through the MSDN article How the Runtime Locates Assemblies and also reading this, I am still unsure about how weakly named assemblies are resolved at runtime.
Eg. if I have a reference to some dll file in my project, I compile and deploy, will it pick up a new version of the referenced dll file if I just replace the old one which was actually referenced at compile time? Does it matter if the reference in the project file specifies the version etc. of the referenced assembly?
Any enlightenment welcome
If the assembly is not found in the GAC then the CLR will search for it in the "probing path". Which by default is only the directory that contains the EXE. It only looks for a match on the assembly name and will stop searching on the first match.
It then checks the [AssemblyVersion] number. If it doesn't match you'll get an exception, it won't keep looking for another assembly with the same name. Whenever you have resolution trouble, you'll want to use the Fuslogvw.exe utility. It shows you exactly where the CLR looked and what went wrong.
The best place that I've found to learn about this is in Grimes Fusion Workshop as can be found here. It is very comprehensive while still easy to understand.
The answer to your questions is yes as long as long as you have Specific Version set to False in the properties for the reference to the assembly.
If version is not mentioned it will pick up the reference, if the version is mentioned it will try to find and load the assembly matching the signature with version mentioned. if not found it will throw an exception. To resolve this you can do assembly binding redirection.