不加載這不是一個重複的 - 我已對相關的StackOverflow問題,沒有運氣:How to Load an Assembly to AppDomain with all references recursively?動態加載大會在新的AppDomain
我有兩個控制檯應用程序。 AssemblyLoaderTest.exe和testapp.exe
- 我試圖用AssemblyLoaderTest.exe動態地從一個類中testapp.exe
- 加載testapp.exe和調用一個方法到目前爲止代碼工作 - 方法「 Testapp.exe中的「TestWrite()」正確執行(並且寫入outputsuccess.txt),但是,testapp.exe加載到同一AppDomain中,這經驗證是因爲「CallMethodFromDllInNewAppDomain」始終返回false。我試圖在新AppDomain中加載testapp.exe。
我的問題:如何修改下面的代碼,以便testapp.exe加載到新的AppDomain中,結果「CallMethodFromDllInNewAppDomain」返回true?謝謝!
下面的代碼。兩者都可以簡單地複製到VS中的新控制檯應用程序中並執行/編譯。
控制檯應用程序#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)
{
// Code always comes here
return false;
}
else
{
// This would prove the assembly was loaded in a NEW domain. Never gets here.
return true;
}
}
public static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
// This is required I've found
return System.Reflection.Assembly.LoadFrom(ExeLoc);
}
}
}
控制檯應用程序#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);
}
}
}
邁克爾,感謝您的評論。 (2)將不可能用於我的用例(因爲這不允許我通過名稱調用類/方法)。 (3) - 我添加了domaininfo.ApplicationBase = System.IO.Path.GetDirectoryName(exePath);,但實際上它根本沒有做任何事情(outputsuccess.txt仍然寫入父AppDomain的當前目錄)。 – BlueSky
如果您可以編輯我現有的代碼並使其工作,將不勝感激。關於這個主題的理論有很多討論,但還沒有找到一個有效的代碼示例。謝謝! – BlueSky
我剛剛完全清除並重新創建了我的帖子。這應該回答你的問題。 –