views:

4878

answers:

8

I posted a similar question a time ago. I need to load an assembly at runtime.

This is easy if I know the absolute path of the dll at runtime.

But I dont :( The assembly.Load() or LoadFromFile() fails if the file is not in the application root.

The only thing I have is the dll name. The dll could be located in the root, system32 or in even in the GAC.

Is it possible for .net to automatically determine where the dll is at, like for example : it should first look in the root. If its not there move on to the system folders, else try the GAC.

EDITED

I am using plug-in architecture. I do not need to register the dll. I have a multi user application. I have a applications table containing information regarding applications. Each application has a dll path associated with it, containing certain algorithms associated with that app. Hope this helps.

+1  A: 

The dll will be found automatically is it is in some location referenced in the PATH system variable (i.e., system32) or if the dll is registered. You can't find it if it can be anywhere on disk, but no one needs that functionality anyway.

EDIT: can the dll's be registered? how are you getting the assembly name if you don't know of the assembly ahead of time? Are you creating some type of plug-in architecture? I think it would help if you explained your situation a bit more.

EDIT2: If that is the case, why not provide a way for the user to register his or her plug in? You can get all the information that you need from an open file dialog. That or simply make them dump it into a folder that you specify.

Ed Swangren
when I call the assembly.Load("myassembly.dll") and I put the dll in my system32, it does not work.
MegaByte
I think this works for unmanaged DLLs not managed ones. See Lonzo's post for what I think what is a better response.
Gishu
A: 

Register this assembly into the GAC. How to do that

abatishchev
+1  A: 

You can hook up into AppDomain.CurrentDomain.AssemblyResolve event and load the assembly for your application manually on demand.

lubos hasko
Ok, so once i have set all the additional paths - how do I tell the CLR to load the assembly ? Do I still use the Load() method?
MegaByte
exacly... but besides your app directory and GAC, it will also search automatically for assembly in those folders.
lubos hasko
FWIW The above method is deprecated though in favor of AppDomainSetup.PrivateBinPath. See http://msdn.microsoft.com/en-us/library/system.appdomain.appendprivatepath.aspx
Gishu
@lubos The private path, or relative search path, is the path relative to the base directory where the assembly resolver probes for private assemblies. Your solution above doesn't work.
Leyu
@Leyu, thanks. you are right, it was long time ago I was doing this. the first part of answer removed.
lubos hasko
+1  A: 

Yes there is a way and it depends on whether your dll is weakly(without a public key token) or strongly(with a public key token) named. If its weakly named and you have added a reference to the assembly with the dll within VS, then VS will first look in the application folder root and if it does not find it, it will then look in the subdirectories that you specify as the value of the privatePath attribute in your XML config file.

If its a strongly named dll, then the CLR will search in the GAC so you need to install the dll in the GAC. The CLR can also look in the application directory if you install an XML config file that has its codeBase element pointing to the dll's path.

To specify an assembly in the GAC you can use the /reference:[DLL name] switch when compiling your assembly.

Lonzo
What if it is weakly named and I dont add the reference of the assembly within VS ?
MegaByte
he can't use /reference since he is loading DLLs at run time.. also the /ref switch is for any ref assembly (irrespective of GAC or private)
Gishu
A: 

I hope you've read up on the following. My suggestion...

  • How the runtime locates assemblies
  • You can give Assembly.LoadWithPartialName a whirl.. might work.. it says it will search the application folder and the GAC unlike Assembly.Load. (However its less safe.. coz you might end up with the wrong version of the DLL since you dont specify all 4 parts of the Assembly Name)
  • Also try AppDomainSetup.PrivateBinPath (AppDomain.AppendPrivatePath has been deprecated in favor of this) to add subfolders of the application root to the list of folders to probe assemblies for. You can also try copying over files from other places into a [AppFolder]\MySandboxForDLLsToLoad, which is added to the PrivateBinPath.
Gishu
A: 

Use this Assembly.LoadWithPartialName(assemblyName);

+1  A: 

When the current application looks for assemblies, it looks in several locations (bin folder, gac, etc..) if it can not find one, then the developer needs to manually tell the application where to look. You can do this by intercepting the AssemblyResolve event, and using the event args to tell the CLR where your assembly is.

AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
....................
Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
   var strTempAssmbPath=
          Path.GetFullPath("C:\\Windows\\System32\\" + args.Name.Substring(0,  args.Name.IndexOf(",")) + ".dll");

   var strTempAssmbPath2=
          Path.GetFullPath("C:\\Windows\\" + args.Name.Substring(0,  args.Name.IndexOf(",")) + ".dll");


    if (File.Exists(strTempAssmbPath))
            return Assembly.LoadFrom(strTempAssmbPath);

    if (File.Exists(strTempAssmbPath2))
            return Assembly.LoadFrom(strTempAssmbPath2);
}
Climber104
A: 

You have three options

  1. Install the assembly in the global assembly cache (GAC)
  2. Use an application configuration (.config) file with the tags
  3. Use the AssemblyResolve event

You can find the details here.

Leyu