This is not a duplicate. I examined this related StackOverflow question with no luck: How do I load an assembly in AppDomain with all the recursive links?
I have two console applications. AssemblyLoaderTest.exe and testapp.exe
- I am trying to use AssemblyLoaderTest.exe to dynamically load testapp.exe and call a method from a class in testapp.exe
- While the code is working, the testWrite () method in testapp.exe is executed correctly (and outputsuccess.txt is output), however, testapp.exe is loaded into the same AppDomain , which is proven because "CallMethodFromDllInNewAppDomain" always returns false. I am trying to load testapp.exe in a new AppDomain .
My question is: how can I change the code below so that testapp.exe is loaded into the new AppDomain, and as a result of "CallMethodFromDllInNewAppDomain" returns true? Thanks!
The code is below. Both can simply be copied to new console applications in VS and executed / compiled.
Console Application # 1:
using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Security.Policy; namespace AssemblyLoaderTest { class Program { static void Main(string[] args) { List<object> parameters = new List<object>(); parameters.Add("Test from console app"); bool loadedInNewAppDomain = DynamicAssemblyLoader.CallMethodFromDllInNewAppDomain(@"c:\temp\testapp.exe", "testapp.TestClass", "TestWrite", parameters); } } public static class DynamicAssemblyLoader { public static string ExeLoc = ""; public static bool CallMethodFromDllInNewAppDomain(string exePath, string fullyQualifiedClassName, string methodName, List<object> parameters) { ExeLoc = exePath; List<Assembly> assembliesLoadedBefore = AppDomain.CurrentDomain.GetAssemblies().ToList<Assembly>(); int assemblyCountBefore = assembliesLoadedBefore.Count; AppDomainSetup domaininfo = new AppDomainSetup(); Evidence adevidence = AppDomain.CurrentDomain.Evidence; AppDomain domain = AppDomain.CreateDomain("testDomain", adevidence, domaininfo); AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve); domain.CreateInstanceFromAndUnwrap(exePath, fullyQualifiedClassName); List<Assembly> assemblies = domain.GetAssemblies().ToList<Assembly>(); string mainExeName = System.IO.Path.GetFileNameWithoutExtension(exePath); Assembly assembly = assemblies.FirstOrDefault(c => c.FullName.StartsWith(mainExeName)); Type type2 = assembly.GetType(fullyQualifiedClassName); List<Type> parameterTypes = new List<Type>(); foreach (var parameter in parameters) { parameterTypes.Add(parameter.GetType()); } var methodInfo = type2.GetMethod(methodName, parameterTypes.ToArray()); var testClass = Activator.CreateInstance(type2); object returnValue = methodInfo.Invoke(testClass, parameters.ToArray()); List<Assembly> assembliesLoadedAfter = AppDomain.CurrentDomain.GetAssemblies().ToList<Assembly>(); int assemblyCountAfter = assembliesLoadedAfter.Count; if (assemblyCountAfter > assemblyCountBefore) {
Console application # 2:
using System; namespace testapp { class Program { static void Main(string[] args) { Console.WriteLine("Hello from console"); } } [Serializable] public class TestClass : MarshalByRefObject { public void TestWrite(string message) { System.IO.File.WriteAllText(@"outputsuccess.txt", message); } } }
source share