C# 将值从其他应用程序域传递到主(主)应用程序域
由此,我可以将一个dll加载到应用程序域中,并获取该dll中的类型,如果需要,可以在临时域的函数中打印它们。但是我现在想把这些类型传递回主域(它有Main)。我发现这意味着我需要将我的对象包装在一个MarshalByRef类型的类中,并将其作为参数传递,我尝试了这一点,但得到了一个异常。以下是我所做的(从第一个链接线程中@Scoregraphic给出的示例稍作修改) 我得到一个例外: 无法加载文件或程序集的abc, 版本=1.0.0.5,区域性=中性,PublicKeyToken=null'或一个 它的依赖性。系统找不到指定的文件C# 将值从其他应用程序域传递到主(主)应用程序域,c#,reflection,appdomain,remoting,C#,Reflection,Appdomain,Remoting,由此,我可以将一个dll加载到应用程序域中,并获取该dll中的类型,如果需要,可以在临时域的函数中打印它们。但是我现在想把这些类型传递回主域(它有Main)。我发现这意味着我需要将我的对象包装在一个MarshalByRef类型的类中,并将其作为参数传递,我尝试了这一点,但得到了一个异常。以下是我所做的(从第一个链接线程中@Scoregraphic给出的示例稍作修改) 我得到一个例外: 无法加载文件或程序集的abc, 版本=1.0.0.5,区域性=中性,PublicKeyToken=null'或一
如果我从函数中删除tlw参数并删除此赋值,它就可以正常工作。我完全被难住了。任何privatebinpath都必须是任何应用程序域基本路径的子目录。您没有设置子应用程序域基本路径,因此它可能将使用当前的应用程序域基本路径。我猜abc.dll的路径不在父bin文件夹的子目录中,这是:
domain.createInstanceFromandWrap(pathToDll,typeof(InstanceProxy).FullName)as InstanceProxy
必须返回null
,因为您正在从abc.dll创建InstanceProxy
的实例,并从主组件将其铸造到InstanceProxy。你确定,这是你的真实代码吗?不,它工作得很好,只是我的命名不好path
是指向外部dll的路径,但pathToDll
是主(主)域的路径。我正在CreateInstanceFromAndUnwrap
中使用pathToDll
。我将编辑名称以使其更有意义。我相信问题在于,新创建的AppDomain不知道您的TypeListWrapper
对象,因为它找不到包含它的DLL。您可以尝试将ApplicationBase=AppDomain.CurrentDomain.BaseDirectory
添加到domainSetup
中。这是正确的,外部dll位于完全不同的文件夹层次结构中。如果我从安装对象中删除'PrivateBinPath',我仍然会在同一行中得到相同的错误。如何解决此问题?将包含abc.dll的文件夹复制到主应用程序文件夹中,并将新路径设置为privatebinpath abc.dll非常感谢jaywayco。我被困在这个问题上差不多一天了,你帮我从更多的挫折中解脱出来:)如果我直接将所有DLL复制到bin文件夹中,事情会成功,但是如果我在bin下创建一个新文件夹,然后将它们复制到那里,当我尝试在程序集上执行GetTypes()时,我会得到FileNotFound。你知道我该怎么做吗?是否需要以其他方式设置应用程序域?将privatebinpath设置为bin下的新文件夹
public class TypeListWrapper : MarshalByRefObject
{
public Type[] typeList { get; set; }
}
internal class InstanceProxy : MarshalByRefObject
{
public void LoadLibrary(string path, TypeListWrapper tlw)
{
Assembly asm = Assembly.LoadFrom(path);
var x = asm.GetExportedTypes();//works fine
tlw.typeList = x;//getting exception on this line
}
}
public class Program
{
public static void Main(string[] args)
{
string pathToMainDll = Assembly.GetExecutingAssembly().Location;
string pathToExternalDll = "/path/to/abc.dll";
try
{
AppDomainSetup domainSetup = new AppDomainSetup
{
PrivateBinPath = pathToMainDll
};
AppDomain domain = AppDomain.CreateDomain("TempDomain", null, domainSetup);
InstanceProxy proxy = domain.CreateInstanceFromAndUnwrap(pathToMainDll , typeof(InstanceProxy).FullName) as InstanceProxy;
TypeListWrapper tlw = new TypeListWrapper();
if (proxy != null)
{
proxy.LoadLibrary(pathToExternalDll , tlw);
}
AppDomain.Unload(domain);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + Environment.NewLine + ex.StackTrace);
}
Console.ReadLine();
}
}