It is frustrating when the .NET runtime is unable to load an assembly because it cannot find it. This C# example demonstrates how to tell the .NET runtime where to look for assemblies it could not find. The C# source and project files can be downloaded from this URL:
C# Load Assembly Example Project
To tell the .NET runtime where to look for an assembly, follow these steps:
- After adding the reference to the assembly within Visual Studio, set the "Copy Local" property of the Reference to False. This prevents the assembly DLL from being copied to the application’s bin directory.
- In the Form’s load event, add an event handler for the AssemblyResolve event for the current AppDomain. (It’s easy and requires two lines of code — have a look at the code below.)
- Create an AssemblyResolve event handler. You may use the implementation as-is from the source code below. There is only a single line of code that may need to be changed, and it is marked in boldface.
The AssemblyResolve event is called whenever the .NET runtime cannot locate an assembly. This is where your code will load the assembly by calling Assembly.LoadFrom.
To test with the Chilkat .NET assembly for the 2.0 Framework, follow these steps:
- Download and install the Chilkat .NET component from this URL: Chilkat .NET Assembly for the 2.0/3.5 Framework
- Download the sample project: C# Load Assembly Example Project
- Open the project in Visual Studio 2005, remove the reference to ChilkatDotNet2, and re-add it by browsing to the ChilkatDotNet2.dll located in the folder where the Chilkat .NET Assembly was installed (typically C:\Program Files\Chilkat Software Inc\Chilkat.NET-v2.0-Framework).
- Set the "Copy Local" property of the reference to False.
- Create a "c:\MyAssemblies" directory an copy the ChilkatDotNet2.dll to it.
- Build and run the program. The DLL should load from c:\MyAssemblies. If not, the exception information will be displayed in a textbox.
Complete C# Source Code Listing (.NET 2.0 Framework, Visual Studio 2005):
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
namespace AssemblyLoad
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//The AssemblyResolve event is called when the common language runtime tries to bind to the assembly and fails.
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(currentDomain_AssemblyResolve);
}
Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
//This handler is called only when the common language runtime tries to bind to the assembly and fails.
//Retrieve the list of referenced assemblies in an array of AssemblyName.
Assembly MyAssembly, objExecutingAssemblies;
string strTempAssmbPath = "";
objExecutingAssemblies = Assembly.GetExecutingAssembly();
AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
//Loop through the array of referenced assembly names.
foreach (AssemblyName strAssmbName in arrReferencedAssmbNames)
{
//Check for the assembly names that have raised the "AssemblyResolve" event.
if (strAssmbName.FullName.Substring(0, strAssmbName.FullName.IndexOf(",")) == args.Name.Substring(0, args.Name.IndexOf(",")))
{
//Build the path of the assembly from where it has to be loaded.
//The following line is probably the only line of code in this method you may need to modify:
<strong>strTempAssmbPath = txtAssemblyDir.Text;</strong>
if (strTempAssmbPath.EndsWith("\\")) strTempAssmbPath += "\\";
strTempAssmbPath += args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
break;
}
}
//Load the assembly from the specified path.
MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
//Return the loaded assembly.
return MyAssembly;
}
private void UseChilkat()
{
Chilkat.Zip zip = null;
zip = new Chilkat.Zip();
MessageBox.Show(zip.Version);
textBox1.Text = "Success.";
}
private void button1_Click_1(object sender, EventArgs e)
{
try
{
UseChilkat();
}
catch (Exception e2)
{
textBox1.Text = e2.Message;
}
}
}
}