Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load assembly from Path

Tags:

c#

gac

I need to load an assembly from a certain location and not from the GAC. I can not remove the assembly from the GAC, because my program has to run on different machines, where I couldn't control if the assembly is in the GAC or not.

I added a reference to the DLL-File to my project. Unfortuntely the assembly is loaded from the GAC.

I've tried the following code in my App.xaml.cs in the Startup-Event

var directory = Thread.GetDomain().BaseDirectory;
var dllPath = Path.Combine(directory, "MyAssembly.dll");
var assembly = Assembly.LoadFrom(dllPath);

Unfortunately the assembly is still loaded from the GAC.

What can I do to load it from the given location, even if the assembly is in GAC?

like image 242
Tomtom Avatar asked May 26 '14 13:05

Tomtom


2 Answers

Unfortunately, you won't be able to bypass the GAC - Assembly.LoadFrom(), Assembly.LoadFile(), and even loading it into a byte array and using Assembly.Load(byte[]) will all check the GAC first for an assembly with the same identity, and load it instead.

You used to be able to do what you want in .net 1.1, but since 2.0, the GAC is checked first. See How the Runtime Locates Assemblies - note that step 3 is check the GAC, before probing directories (even if you you fully specified it)

If you want to load one up for Reflection (examining the assembly, rather than running it), you can use Assembly.ReflectionOnlyLoadFrom()

like image 130
Philip Rieck Avatar answered Sep 17 '22 14:09

Philip Rieck


Check out Assembly.LoadFrom() on MSDN.

From MSDN:

Assembly SampleAssembly;
SampleAssembly = Assembly.LoadFrom("c:\\Sample.Assembly.dll");
// Obtain a reference to a method known to exist in assembly.
MethodInfo Method = SampleAssembly.GetTypes()[0].GetMethod("Method1");
// Obtain a reference to the parameters collection of the MethodInfo instance.
ParameterInfo[] Params = Method.GetParameters();
// Display information about method parameters. 
// Param = sParam1 
//   Type = System.String 
//   Position = 0 
//   Optional=False 
foreach (ParameterInfo Param in Params)
{
    Console.WriteLine("Param=" + Param.Name.ToString());
    Console.WriteLine("  Type=" + Param.ParameterType.ToString());
    Console.WriteLine("  Position=" + Param.Position.ToString());
    Console.WriteLine("  Optional=" + Param.IsOptional.ToString());
}

Even after loading your custom assembly, you cannot simply invoke your method or use types as you normally would. Check out this example, stolen from this question, which should point you in the right direction:

 Assembly assembly = Assembly.LoadFile("myAssembly");
        Type type = assembly.GetType("myAssembly.ClassName");
        if (type != null)
        {
            MethodInfo methodInfo = type.GetMethod("MyMethod");
            if (methodInfo != null)
            {
                object result = null;
                ParameterInfo[] parameters = methodInfo.GetParameters();
                object classInstance = Activator.CreateInstance(type, null);
                if (parameters.Length == 0)
                {
                    //This works fine
                    result = methodInfo.Invoke(classInstance, null);
                }
                else
                {
                    object[] parametersArray = new object[] { "Hello" };

                    //The invoke does NOT work it throws "Object does not match target type"             
                    result = methodInfo.Invoke(classInstance, parametersArray);
                }
            }
        }
like image 33
James Hill Avatar answered Sep 16 '22 14:09

James Hill