加载依赖于另一个域的程序集时的 FileNotFound [重复]

Posted

技术标签:

【中文标题】加载依赖于另一个域的程序集时的 FileNotFound [重复]【英文标题】:FileNotFound when load assembly with dependency to another domain [duplicate] 【发布时间】:2013-05-04 23:56:32 【问题描述】:

我正在尝试使用插件制作应用程序。

我有 MainLib.dll,我在其中使用 1 种方法创建了一些通用接口(让它成为 ICommon)。然后,我制作了 2 个引用 MainLib.dll 的 .dll(插件),并在某些类中实现了 ICommon。此外,我删除了此 .dll 中的所有引用,例如 System

然后,我创建了一个应用程序,它监视文件夹".\\Plugins" 并加载newDomain 中的所有.dll,检查.dll 中的类型是否实现ICommon(因此该应用程序也引用了MainLib.dll)。如果是 - 在某个列表中添加 .dll 的名称。

现在问题来了: 在我尝试加载插件之前 - 我将 MailLib.dll 和 System 加载到 newDomain,因为所有插件都依赖于这个 .dll。他们加载正确。然后,我开始加载插件,这里有:

FileNotFoundException,无法加载文件或程序集“PluginWithException,版本=1.0.0.0,Culture=neutral,PublicKeyToken=null”或其依赖项之一。系统找不到指定的文件。) on string Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName);

PluginWithException 程序集只有 2 个依赖项 - System 和 MainLib。在我尝试加载 PluginWithException 之前,我检查了新域中的程序集,System 和 MainLib 已加载到该域。所以我看不到任何有依赖性的问题。我阅读了this 主题,并尝试了ProxyDomain 的解决方案,但例外情况相同。

我做错了什么?

代码如下:

public static List<string> SearchPlugins(string[] names)

    AppDomain domain = AppDomain.CreateDomain("tmpDomain");
    domain.Load(Assembly.LoadFrom(@".\MainLib.dll").FullName);
    domain.Load(@"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
    MessageBox.Show(GetAssembies(domain)); // here I can see that System and MailLib exist in new domain

    List<string> plugins = new List<string>();

    foreach (string asm in names)
    
        Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName); // here I have exception

        var theClassTypes = from t in loadedAssembly.GetTypes()
                            where t.IsClass &&
                                  (t.GetInterface("ICommonInterface") != null)
                            select t;
        if (theClassTypes.Count() > 0)
        
            plugins.Add(asm);
        
    
    AppDomain.Unload(domain);
    return plugins;

【问题讨论】:

【参考方案1】:

你可能想告诉域从哪里加载你的程序集:

AppDomain domain = AppDomain.CreateDomain("tmpDomain", null, new AppDomainSetup  ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins") );

但是,我不明白您为什么要在当前(默认)域以及 tmpDomain 中加载程序集。

【讨论】:

谢谢,我试过你的代码,但例外是一样的,在同一行。我的目标是不在默认域中加载程序集,因为我不想在应用程序中保留垃圾(如果图像,它将超过 100 个插件),所以我可以加载一些插件,使用它,然后将其从应用程序中丢弃,当我不需要它。 OK - 但是当您执行Assembly.LoadFrom(asm) 时,它将加载到当前域中。这违背了你的目的。我建议你有一个PluginLoader 自定义类并将该类加载到 tmpDomain 中。然后您可以在该类中编写代码以使用Assembly.LoadFrom 加载所有插件并返回您想要的插件列表。 使用sysinternals进程浏览器——你可以随时找到在哪个域中加载了什么。

以上是关于加载依赖于另一个域的程序集时的 FileNotFound [重复]的主要内容,如果未能解决你的问题,请参考以下文章

下拉列表依赖于另一个? ASP.NET MVC

如何制作依赖于另一个应用程序的Android应用程序?

使用 .net 4.0 测试程序集测试 .net 3.5 程序集时的风险有多大

datagridviewcombobox columns 依赖于另一列

加载管道程序集时出错

依赖于另一个自创建库的自创建库