C# 4.0 在新appdomain中启动第三方DLL中存在的方法

C# 4.0 在新appdomain中启动第三方DLL中存在的方法,c#-4.0,appdomain,C# 4.0,Appdomain,我想在新的应用程序域中调用SayHello()方法。假设HelloMethod DLL是第三方,我没有代码。我只有一台电脑。但我知道它有SayHello()方法。我能做什么 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace DoCallBack { class Program { static void Main(stri

我想在新的应用程序域中调用SayHello()方法。假设HelloMethod DLL是第三方,我没有代码。我只有一台电脑。但我知道它有SayHello()方法。我能做什么

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DoCallBack
{
    class Program
    {
        static void Main(string[] args)
        {
            AppDomain newDomain = AppDomain.CreateDomain("New Domain");
            Console.WriteLine(newDomain.BaseDirectory);
            newDomain.DoCallBack(new CrossAppDomainDelegate(SayHello));
            AppDomain.Unload(newDomain);
        }
    }
}

在当前代码中,其给定错误“当前上下文中不存在名称'SayHello'”

如果程序集尚未加载,则必须加载该程序集。有两种方法可以做到这一点:

  • 引用项目中的程序集,只需执行以下操作:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace HelloMethod
    {
        class Program
        {
            static void Main(string[] args)
            {
            }
    
            static void SayHello()
            {
                Console.WriteLine("Hi from " + AppDomain.CurrentDomain.FriendlyName);
            }
        }
    }
    
    如果您不介意在自己的项目中引用第三方程序集,这是可以的。这也意味着您在编译时知道要调用的程序集、类型和方法

  • 自己加载第三方程序集并执行特定方法:

    newDomain.DoCallBack(new CrossAppDomainDelegate(HelloMethod.Program.SayHello));
    
    //
    ///要使用AppDomain.docCallback方法在新AppDomain中执行。
    /// 
    静态void GenericCallBack()
    {                       
    //可以从其他地方加载这些文件,如配置文件。
    var thirdPartyAssemblyFileName=“ThirdParty.dll”;
    var targetTypeFullName=“HelloMethod.Program”;
    var targetMethodName=“SayHello”;
    尝试
    {
    var thirdPartyAssembly=Assembly.Load(AssemblyName.GetAssemblyName(thirdPartyAssemblyFileName));
    var targetType=thirdPartyAssembly.GetType(targetTypeFullName);
    var targetMethod=targetType.GetMethod(targetMethodName);
    //这只适用于静态方法!
    Invoke(null,null);
    }
    捕获(例外e)
    {
    Console.WriteLine(“回调失败。错误信息:”);
    控制台写入线(e);
    }
    }
    
    如果您正在寻找一种更灵活的方法从第三方程序集调用公共静态方法,可以使用这种方法。请注意,几乎所有内容都包含在try-catch中,因为这里有很多东西可能出错。这是因为每个“反射”调用都可以抛出异常。最后,请注意,这种方法的工作原理是让第三方程序集及其所有依赖项位于应用程序的基本目录或其中一个专用bin路径中


  • 谢谢分配,是否需要新的CrossAppDomainDelegate?为什么没有这个我们可以跑?@SHRI这是必要的!编译器为您声明的每个委托类型生成代码。CrossAppDomainDelegate可能让编译器知道委托应该从MarshalByRefObject派生,以允许跨AppDomain通信。这是我的猜测。重要的是,您需要使用CrossAppDomainDelegate。
    /// <summary>
    /// To be executed in the new AppDomain using the AppDomain.DoCallBack method.
    /// </summary>
    static void GenericCallBack()
    {                       
        //These can be loaded from somewhere else like a configuration file.
        var thirdPartyAssemblyFileName = "ThirdParty.dll";
        var targetTypeFullName = "HelloMethod.Program";
        var targetMethodName = "SayHello";
    
        try
        {
            var thirdPartyAssembly = Assembly.Load(AssemblyName.GetAssemblyName(thirdPartyAssemblyFileName));
    
            var targetType = thirdPartyAssembly.GetType(targetTypeFullName);
    
            var targetMethod = targetType.GetMethod(targetMethodName);
    
            //This will only work with a static method!           
            targetMethod.Invoke(null, null);             
        }
        catch (Exception e)
        {
            Console.WriteLine("Callback failed. Error info:");
            Console.WriteLine(e);
        }
    }