I'm trying to load a DLL file into a separated app domain and invoke a method in the DLL file and get some response from it. The DLL file did not exist in the project bin
folder when the application starts, the DLL file is loaded from another folder. After I have done with the DLL file I want to unload the app domain that I have just created.
The steps:
- Created a new app domain
- Load my DLL I want to the app domain
- Invoke the method and get response
- Unload the app domain
Here is what I've tried so far
This is the code in MyAssembly.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MyAssembly
{
public class MyClass
{
public static string MyMethod()
{
return "Hello there, this is message from MyAssembly";
}
}
}
Here is how I load the DLL file
using System.Diagnostic;
using System.IO;
private class ProxyClass : MarshalByRefObject
{
public void LoadAssembly()
{
AppDomain dom;
string domainName = "new:" + Guid.NewGuid();
try
{
//Create the app domain
dom = AppDomain.CreateDomain(domainName, null, new AppDomainSetup
{
PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"),
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
ShadowCopyFiles = "true",
ShadowCopyDirectories = "true",
LoaderOptimization = LoaderOptimization.SingleDomain,
});
string dllPath = @"C:\MyProject\MyAssembly.dll";//the path to my assembly file I want to load
//load the assembly to the new app domain
Assembly asm = dom.Load(File.ReadAllBytes(dllPath));//Error occurred at here
Type baseClass = asm.GetType("MyAssembly.MyClass");
MethodInfo targetMethod = baseClass.GetMethod("MyMethod");
string result = targetMethod.Invoke(null, new object[]{});
/*Do something to the result*/
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.ToString());
}
finally
{
//Finally unload the app domain
if (dom != null) AppDomain.Unload(dom);
}
}
}
public void BeginLoadDll()
{
ProxyClass proxy = new ProxyClass();
proxy.LoadAssembly();
//OR like this, which gave me same error message as well
//var dom = AppDomain.CreateDomain("new:" + Guid.NewGuid(), null, new AppDomainSetup
// {
// PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"),
// ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
// ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
// ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
// ShadowCopyFiles = "true",
// ShadowCopyDirectories = "true",
// LoaderOptimization = LoaderOptimization.SingleDomain,
// });
//ProxyClass proxy = (ProxyClass)dom.CreateInstanceAndUnwrap(
// typeof(ProxyClass).Assembly.FullName, typeof(ProxyClass).FullName);
//pr.LoadAssembly(watcherData, filePath);
}
Here is something I've observed so far, I'm not sure if that is just me or I'm missing something
-If the "MyAssembly.dll" exists in the project bin folder before the application starts, I can load the dll file
-If the "MyAssembly.dll" did not exist in the project bin folder before application starts, instead it was loaded somewhere else other than the project bin folder, I cannot load the dll file. For example, the project bin folder is "C:\Main\MyMainProject\MyMainProject\bin", and DLL is loaded from C:\MyProject\MyAssembly.dll"
-If I move the "MyAssembly.dll" file into the bin folder (using File.Copy()
or File.Move()
), it somehow stop the rest of the code to be executed.
The error message I received
Could not load file or assembly 'MyAssembly, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=2c20c56a5e1f4bd4' or one of its dependencies.
The system cannot find the file specified.
EDIT
I know I can use Assembly.LoadFrom(@"PATH\TO\MY\DLL")
, but the problem with this one is I cannot unload the DLL