【问题标题】:Using AppDomain in C# to dynamically load and unload dllC#中使用AppDomain动态加载和卸载dll
【发布时间】:2011-07-05 05:14:09
【问题描述】:

在我的一个与系统诊断相关的应用程序中,相关的 DLL 将在 C# 中动态加载和卸载。经过一番搜索,我发现无法动态加载单独的 DLL,它是完整的 AppDomain。所以我必须创建一个 AppDomain 并使用该 DLL 来动态加载卸载。但我找不到任何地方如何在代码中使用它。由于违反公司规定,我无法显示应用代码。

谁能告诉我一些应用程序代码来使用它。我想使用 appdomain 动态加载和卸载 dll 并在该 dll 中调用特定方法,该 dll 没有任何入口点。

感谢您的回答。 阿舒托什

【问题讨论】:

    标签: c#


    【解决方案1】:

    How to: Load Assemblies into an Application Domain

    public static void Main()
    
    
        {
            // Use the file name to load the assembly into the current
            // application domain.
            Assembly a = Assembly.Load("example");
            // Get the type to use.
            Type myType = a.GetType("Example");
            // Get the method to call.
            MethodInfo myMethod = myType.GetMethod("MethodA");
            // Create an instance.
            object obj = Activator.CreateInstance(myType);
            // Execute the method.
            myMethod.Invoke(obj, null);
        }
    

    至于怎么卸载,就得自己卸载AppDomain了,见this

    AppDomain Temporary = AppDomain.CreateDomain("Temporary");
    try
    {
      Gateway Proxy = 
        (Gateway) Temporary.CreateInstanceAndUnwrap("Shim", "Shim.Gateway");
    
      Match M = Proxy.LoadAndMatch("Plugin.dll", 
        "Though the tough cough and hiccough, plough them through");  
    }
    finally
    {
      AppDomain.Unload(Temporary);
    }
    

    【讨论】:

    • 我是否必须创建一个单独的 Main 入口点,在单独的 AppDomain 中调用 DLL 以使用 AppDomain 的加载和卸载来加载和卸载 dll...?
    • 没有什么叫做单独的主入口点。如果您的应用程序是 Winforms 应用程序,则已经有一个入口点。如果您的应用程序是 Web 应用程序,则 global.asax 中有 Application_Start 方法。
    • 回复:首先要回答的评论:他需要关于 .NET 远程处理的参考,该示例没有解释也没有明确说明远程处理正在用于辅助应用程序域中组件的激活/RPC。
    【解决方案2】:

    您的问题很难理解,但我会尽力提出一些建议。

    没有理由你不能在没有单独的应用程序域的情况下将 dll 直接动态加载到你的应用程序中,诀窍是你不能卸载它。仅当您可以加载同一 dll 的多个版本时,这才重要(即,您希望能够将此诊断组件更新到新版本而不停止应用程序的执行)。如果这就是你想要做的,那么我建议this CodeProject article

    【讨论】:

    • C# Dll 是一个诊断程序,它在内部调用一些 win32 dll,为被测硬件加载设备驱动程序。测试完成后,需要重置它,关闭应用程序会从内存中释放所有内存和驱动程序,从而重置硬件。现在我不想关闭应用程序,而是卸载 C# dll,这最终将通过卸载相关的 win32 dll 和驱动程序来重置硬件,这需要 AppDomain。我不太确定如何使用它...???
    • AppDomains 肯定会解决您的 Win32 内存问题。尽管在大多数情况下,您应该能够通过进行适当的清理/删除调用来释放 Win32 API 使用的绝大多数内存。但是,如果您想要卸载 AppDomain,那么上面的答案中会发布大量示例。如果您仍有问题,则必须更具体。
    【解决方案3】:

    实际上,您可以将程序集动态加载到您的应用程序域并从中运行代码,问题是您无法卸载程序集。但是,您可以加载其他应用程序域(以及其中的程序集)并在完成后卸载应用程序域。

    正如它的名字所暗示的那样,你有了一个新的应用程序域,你不能只是简单地调用它的代码并使用你需要的类型来跨域边界编组你的调用和数据。如果您搜索,您会发现很多关于如何执行此操作的示例。

    需要考虑的是,这是一种常见的模式,并且有现成的解决方案,框架本身有一个完整的插件命名空间,专门用于这种类型的插件行为,它可能值得你在仔细观察之前。有一篇文章here 展示了如何使用它。

    【讨论】:

      【解决方案4】:

      谢谢大家,这是我找到问题答案的链接:

      The MSDN forum description for load and unload of assemblies dynamically

      可以使用另一个加载程序集的类动态加载和卸载其他 dll,并调用该程序集中的方法... AppDomain.CreateInstanceAndUnwrap 通常希望输入作为来自当前项目或通常当前命名空间的程序集。解决我需要 Assembly.LoadFrom();要在其他类中使用并创建 AppDomain 并使用链接中给出的 AppDomain 对象创建此类的实例。

      谢谢你们的回复。

      【讨论】:

      • 这并不能保证 DLL/程序集被卸载。
      猜你喜欢
      • 2012-11-07
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      • 2010-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多