Assembly.LoadFrom not loading DLL in a different project - c#

I have multiple projects in a given solution.
From ProjectA I pass "myProjectB.dll" as assemblyname to a method call
in ProjectC.
When I execute the following in ProjectC, where assemblyname is "myProjectB.dll"
Assembly assembly = Assembly.LoadFrom(assemblyname);
foreach (Type type in assembly.GetTypes())
{
... my code ...
}
I get the following error
Could not load file or assembly 'file:///C:\MyProjectB\bin\Debug\myProjectB.dll' or one of its dependencies. The system cannot find the file specified.
Please let me know how to pass in the assemblyname properly into Assembly.LoadFrom method call.
How can I provide only the project DLL name and be able to go through the solution and identify the full absolute path for that DLL in the solution at run time. Is it even possible?
Thanks

If the assembly is not located in the exact path as your executable, or in the GAC, you need to give the full path in the LoadFrom method.
For example:
Assembly assembly = Assembly.LoadFrom(#"C:\MyProjectB\bin\Debug\myProjectB.dll");
You can also use relative paths:
Assembly assembly = Assembly.LoadFrom(#"..\..\..\MyProjectB\bin\Debug\myProjectB.dll");

Related

Load Assembly does not work for .net core

I tried
var myAssembly = AssemblyLoadContext.Default.LoadFromAssemblyPath(#"path.to.dll");
Assembly o = Assembly.Load(new AssemblyName(#"path.to.dll"));
open assembly where I have Attributes to read but this two ways do not work in .net core 1.1 How in other way I can load it?
The Assembly.Load Function Does Not Use a Path In Any Way as an Argument,
Therefore You Will Need To Use The Assembly.LoadFile Function,
For Example, I Copied a Random .dll From The System32 Folder To My Desktop,
And Then I Executed The Following Lines:
Assembly assembly = Assembly.LoadFile(#"C:\Users\TomerHorowitz\Desktop\Microsoft.SqlServer.ManagedDTS.dll");
Console.WriteLine(assembly.FullName);
Output:
Microsoft.SqlServer.ManagedDTS, Version=14.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91

Load multiple assemblies

How can I load an assembly using its full display name from a location outside the application's bin path?
Usually one can load an assembly from a custom location with
Assembly.LoadFrom(path);
This works, but it seems that for loading a strong-named assembly I need to specify its full display name such as in
Assembly myDll =
Assembly.Load("myDll, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9b35aa32c18d4fb1");
But the problem here is that this only references assemblies that are in my probing path of my application.
So what if I have an assembly dir1/asm.dll and one assembly dir2/asm.dll and both have a strong name.
How can I load them during runtime?
During Runtime, you can specify additional directories to probe when loading an assembly via the following methods:
AppDomain.CurrentDomain.ClearPrivatePath();
AppDomain.CurrentDomain.AppendPrivatePath();
When the subdirectory names are already known during installation, you can also specify these additional directories in the app.config file in the privatePath attribute of the <probing> element.
Make also sure the file name is correct. When you have
AppDomain.CurrentDomain.AppendPrivatePath("Subdir");
Assembly myDll = Assembly.Load("myDll, Version=1.0.0.1, Culture=neutral, PublicKeyToken=9b35aa32c18d4fb1");
then .net will look for a file named "mydll.dll" in the directory "Subdir" beneath the directory of the executable.
you can load any assembly from its location via loadfile (example here)
if you want to take multiple versions of an assembly consider handling the AppDomain.CurrentDomain.AssemblyResolve (example here)
the examples are from a small open source project, which will load dlls from a seperate a "packages" folder (allowing for packages to have their own copy of a dependency, using the isolated loader)

Reflection - trouble with loading dependent assembly

I am trying to execute below code to see if assembly was built in Debug or Release mode.
Assembly assemb = Assembly.LoadFile(fileName);
bool isDebug = false;
foreach (object att in assemb.GetCustomAttributes(false))
if (att is DebuggableAttribute)
isDebug = ((DebuggableAttribute)att).IsJITTrackingEnabled;
Console.WriteLine("Assembly is {0}.", isDebug ? "debug" : "release");
I am able to load assembly (Product.dll) without any issue. But when I am trying to execute GEtCustomAttributes(false) method I am getting below exception message.
Could not load file or assembly 'log4net, Version=1.2.11.0,
Culture=neutral, PublicKeyToken=null' or one of its dependencies. The
system cannot find the file specified.
Don't know why this is looking for dependent assembly. Is it because of the way Product.dll was build ( like optimization or something ). I don't have access to source code of Product.dll so not sure how I can file its mode ( Debug or Release )
Typically dependent DLLs are not compiled into the resulting DLL. This means that if Product.dll is compiled with a dependency to log4net.dll, it has to be in the same folder.
It should be possible to simply copy log4net.dll into the same folder where Product.dll is located.
The dependency must be loaded if a type defined in Product.dll references a type defined in log4net.dll. In this case I strongly suspect that it will be Logger/ILog, because this line is often included to get the Logger.
private static readonly log4net.ILog log = log4net.LogManager.GetLogger();
If log4net is a mandatory (meaning directly referenced) assembly for your referenced project you have to also load it, there is no way to only load parts of an assembly. Having said this the code for the referenced assembly won´t probably won´t even compile if log4net.dll is missing so it HAS to load it in any way.
Anyway obiosly any of your attributes defined in the referenced assembly needs the Logger from log4net, so it´ll search for that type.
Put the log4net assembly into your build-path and it should work.

can't load assembly with typeof(UserType).AssemblyQualifiedName

I created a class Address in an Assembly MyUserType.dll. I want to load it in a console application. I tried the code below, but it failed:
//cfg.AddAssembly(typeof(Address).AssemblyQualifiedName);
But when i try to use one of the other load assembly methods, it succeeds.
cfg.AddAssembly(Assembly.GetAssembly(typeof(Address)));
cfg.AddAssembly("MyUserType");
The failed msg is:
Message = "Could not load file or assembly 'Ordering.Data.Address, Ordering.Data, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The given assembly name or codebase was invalid. (Exception from HRESULT: 0x80131047)"
Why?
The class Ordering.Data.Address has a reference to an assembly not located in the same directory as the library, MyUserType.dll. Ensure that all referenced assemblies are in the System32 folder, the GAC or the same directory as the library.
Type.AssemblyQualifiedName returns the qualified name for the type, as in it returns the FullName of the type concatenated with the FullName of the containing assembly. You seem to be passing that into Assembly.Load or similar so it obviously fails as that is not a valid assembly name.
To use AssemblyQualifiedName you need to pass it to something like the static Type.GetType(string) method which will parse it correctly.

Trying to load an app through reflection and get error "Could not load file or assembly...The system cannot find the file specified."

The assembly it's trying to find isn't the root assembly - it's a referenced one, but it's in the same folder, and Directory.GetCurrentDirectory() is the folder with all of the files in.
I'm stuck - any suggestions?
You can either:
Create a new AppDomain to load the assembly (and set the AppDomain's base directory to the directory containing all the assemblies).
Attach a handler for AppDomain.AssemblyResolve to help the CLR find the assembly's dependencies.
You might be able to add the directory in question to the list of paths to probe. However, it will need to reside somewhere under your application's directory. See the probe element for more info.
You could try using something like this
string myDll = string.Empty;
string location = Assembly.GetExecutingAssembly().Location;
if (location != null)
{
myDll = string.Format(#"{0}\my.assembly.name.dll", location.Substring(0, location.LastIndexOf(#"\")));
}
This should get physical directory in which the assemblies are running. This could be in the Windows .NET temporary directories. However, because the files are at the same level they should exist there side by side.
If you use assembly.loadfrom you can specify the file path to the assembly.
The load-from context allows an
assembly to be loaded from a path not
included in probing, and yet allows
dependencies on that path to be found
and loaded because the path
information is maintained by the
context.
Executing the program from the folder that has the referenced dll can also solve the problem.

Categories

Resources