4
votes

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.

9

9 Answers

2
votes

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);
}
2
votes

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

1
votes

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.

1
votes

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.

1
votes

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.
1
votes

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.

1
votes

The resolution algorithm used by .NET to find the assemblies and their dependents is straight forward.

  1. .NET identifies the required version. Usually the information about the dependant assemblies is present in the application's assembly manifest.
  2. .NET searches GAC (Global Assembly Cache), only if the assembly is strong named.
  3. If not found in GAC, and if a .config file presnt, then .NET searches the location specified in the cofiguration file, else .NET searches directory containing the executable (.EXE)
  4. After this, If the assembly is still not found, the application terminates with error.

Click here for the video explaining the .net resolution algorithm, and click here for a video on late binding assemblies

0
votes

Register this assembly into the GAC. How to do that

0
votes

Use this Assembly.LoadWithPartialName(assemblyName);