Could not load assembly exception when using Assembly.LoadFile - c#

here's my scenario:
I have three projects: two DLLs and one console application, let's name them foo.dll, bar.dll and console.exe. Console.exe loads foo.dll using Assembly.LoadFile(#"c:\foo.dll"). Foo.dll's project has a reference to bar.dll and makes use of a class. Console.exe loads foo.dll fine, the problem occurs when foo.dll tries to use bar.dll's class. I get a "could not load assembly: "bar.dll" blah blah exception.
Some points:
All projects are strong named
Would prefer to not use the GAC
Bar.dll is in c:\bar.dll
So everything is in the same local directory, the correct dlls are being referenced (via project properties, and I've used Reflector to make sure the assembly versions are correct). If I install bar.dll to the GAC everything works as expected.
I think it has something to do with the Assembly.LoadFile call, and making a hop to the second DLL, but I'm not sure.
Thanks for your time and input.

Assembly.LoadFile() should only ever be used in very special circumstances. The assembly doesn't have a loading context, that's why bar.dll cannot be found. The only real use case is tooling, programs that dump assembly metadata.
Use Load or LoadFrom(). Troubleshoot problems with fuslogvw.exe

Related

Resolving .NET assembly name collision

I currently have a .NET application which references "SomePackage.dll" and "SomeUtilities.dll".
SomePackage.dll is contained in a separate folder, and one of the assemblies it depends on is also named "SomeUtilities.dll".
In other words, I added a reference in my project to \somePath\SomePackage.dll, and there exists a file \somePath\SomeUtilities.dll that SomePackage.dll depends on. Since I already have a reference in my project to a assembly called SomeUtilties.dll, I could not add a reference to \somePath\SomeUtilties.dll.
As a result, when I try to run my application and initialize a module in from SomePackage.dll, I receive an error:
Could not load file or assembly 'SomeUtilities.dll..." or one of its dependencies. The located assembly's manifest definition does not match the assembly reference.'
To work around this, I used gacutil in the VS developer command prompt to add \somePath\SomeUtilities.dll to the GAC. Now both assemblies are resolved fine, but I was wondering if there was a better way to resolve this name collision that doesn't involve adding to the GAC. I'm worried about potential issues that may arise with installing into the GAC, and have heard that .NET has the ability to look through certain subfolders to resolve assemblies, but am not sure where to find more on this concept.
You can use bind redirect.
Open the .config file to find the location of < assemblyBinding>
Remove the < assemblyBinding> reference.
Type in Package Manager Console: Add-BindingRedirect.
Windows/.NET has a tool called FUSLOGVW.exe that will help find issues with assemblies. This tool is useful but sifting through the logs is cumbersome. There is an open source tool that is a wrapper around FUSLOGVW.exe and makes it much easier to sift through the data and find the root of the problem. I would use this
https://github.com/awaescher/Fusion

C# assembly path issue when using ReferencedAssemblies

I'm trying to make a tool similar to Unity (obviously at a lower scale) and I need to be able to compile scripts which work in both the editor and the final game.
My approach to that is compiling the code in the editor using the ReferencedAssembly of my game executable, while the game executable already contains all the scripts which are present in compile time.
However I'm having a problem with the editor part. Basically I set
parameters.ReferencedAssemblies.Add ("path/to/Game.exe");
parameters.GenerateInMemory=true;
parameters.GenerateExecutable=false;
and then compile. There are no compilation errors but when trying to use
var typeArray=results.CompiledAssembly.GetTypes();
a ReflectionTypeLoadException exception is thrown:
Could not load file or assembly 'Game, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies.
However, copying my executable Game.exe to the tool's directory, and changing the reference assembly to
parameters.ReferencedAssemblies.Add ("Game.exe");
allows me to compile and access to GetTypes without errors.
So, my questions are:
a) how can I make GetTypes work when using an assembly which is in another directory? (note: I'd rather not add the path to the GAC, as it should be a generic tool)
b) would it be possible to access type info without loading the referenced assembly? I mean, in NET 4.5 Type and TypeInfo are supposed to be splitted just for this reason, isn't it?
Regarding your point a): "how can I make GetTypes work when using an assembly which is in another directory?
I think you could you use Assembly.LoadFrom Method (String) to load the assembly from another directory.
Regarding your point b): "would it be possible to access type info without loading the referenced assembly?"
I'm not sure you'd be able to access type info without loading it in some fashion, but are you aware of loading Assemblies into the Reflection-Only Context?
The reflection-only load context allows you to examine assemblies compiled for other platforms or for other versions of the .NET Framework. Code loaded into this context can only be examined; it cannot be executed. This means that objects cannot be created, because constructors cannot be executed. Because the code cannot be executed, dependencies are not automatically loaded. If you need to examine them, you must load them yourself.
On a second reading of your question, how does "game.exe" get referenced in your project file?
If it's a case of MSBuild needing to copy it to the build output folder of the project, you could add "game.exe as an item in the project, set the build action to "None" and the Copy to Output Directory Property to "Copy if newer".

Could not load type 'myinterface' from assembly

I have a solution that includes several projects. A few are libs that are building dll's used in my main project in this solution.
My main project builds with output type console application.
This all works fine.
When i change the build output type to a class library (since i want to use this project as a plugin eventually). The project will still build, this time to a dll.
When i use this plugin in an application where i use it as a dll however, it will run up to a certain point where it's trying to load a type defined in an external dll (so NOT built by my solution) and throw the exception:
Could not load type 'externalinterface' from assembly 'externallib, version=3.0.0.0, Culture=neutral, PublicKeyToken=null'.
The dll's are all in the correct folder,etc.
Also worth noting, the plugin is tested in another location than where i built it. The executable still works on this location, the dll/plugin does not. Same amount of dll's in their folders etc.
EDIT: I already used ILSpy (dll inspector) to open the actual dll that is being referenced (so externallib in the errormessage) and checked if 'externalinterface' was present and it is.
EDIT2: RESOLVED! The program that loaded my plugin was loading the same dll that caused the exception. The dll it loaded was of another version than the one i loaded.
Check whether the type externalinterface is present in the referred dll.
You didn't include the details of the exception the application is throwing. However, based on the message you gave, it appears your assembly does not have a strong name. If the application attempting to load your assembly as a plugin does have a strong name, then .NET will require all assemblies loaded by it also have a strong name, so you need to configure your assembly to have a strong name before continuing.
Maybe some supported dll's which is used by the 'externalinterface' is missing in the target machine. In the target machine, check is all the necessary dll's are present in the output folder.
Or blindly copy paste all the dlls in the output folder from the machine where the code is working to the target machine where you have the problem. After this, if the code is working in the target machine, then try to analyze which supporting dll you are missed to copy.

How to bundle a required DLL with a solution in Visual C# (Express, 2010)

I have an application written in C# which interfaces with some custom hardware using a vendor supplied .Net assembly. The .Net assembly in turn loads another DLL at run time. I can add the vendor supplied assembly to my project but when I run it, the vendor assembly complains that it can't load the required DLL. I can work around this for the moment by copying the DLL to the bin\Debug and bin\Release folder.
The problem is that I will need to distribute this application to clients at some point and they will not have this DLL in place. I can't see how I can make the solution require it; I can't add it as a reference since I get the error "A reference to foo.dll could not be added. Please make sure that the file is accessible, and that it is a valid assembly or COM component."
I can't convert the DLL to a .Net assembly using TlbExp, it gives an error "The module was expected to contain an assembly manifest."
I thought if I published the application via "click once" that I could declare the dependency there but I don't see any way for this either. I also tried adding it as a file resource but this didn't seem to help.
I can see other questions on SO relating to how to invoke functionality in an external DLL but in this case, I just need a way to bundle the DLL with the project.
Thanks.
Indicates that the attributed method is exposed by an unmanaged dynamic-link library (DLL)
The DllImportAttribute attribute provides the information needed to call a function exported from an unmanaged DLL. As a minimum requirement, you must supply the name of the DLL containing the entry point.
For further reference go here
Link to Review
You could add the dll as a resource, write it out as a byte[] to a file on loading, and do an Assembly.Load() at runtime for deployment.
You might have to use an AppDomain.AssemblyResolve Event to make sure the assembly resolves in case of multiple versions.
you could add both (all) of the dlls in your project as references and mark them as "copy local". That should do it unless the first DLL expects the second DLL in a specific place.

Can't use an external DLL : FileNotFoundException

I have 2 projects.
The first one just generates a DLL.
The second one needs the first DLL.
But when I call a method from the DLL, I have a FileNotFoundException, with this message :
BDD, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
I'm sure that the file exists.
Where I'm wrong ?
Agree with Kieren (+1). Maybe it is finding your DLL but it requires another dependent DLL that cannot be found. Or is there a signature issue (maybe you are looking for another DLL version, etc...)
To turn on fusion Log (you'll have to create a couple fo registry keys):
BTW, fusion is the DLL that contains the logic to load an assembly (probing for local path and subfolders if specified, looking at the GAC, ...). After running your executable, you'll find a log detailing the issues the CLR has found when loading referenced assemblies (ignore the NativeImage logs, inspect just the Default logs).
Short answer: The DLL needs to be in the same directory as the EXE.
Is this the case?
Could you give the full message - and:
Please bear in mind that the FileNotFoundException could be for a dependency of the referenced DLL, not just the referenced DLL itself.
You might want to turn on assembly-binding log (Fusion log) to see what's going on, if the DLL is indeed present.

Categories