我们正在为我们的插件构建PIP安装程序。该插件由一个DLL中的一个模块组成,我们称之为MyCoolPlugin.dll
(实际上,这个DLL由几个合并的DLL组成)。此外,该插件与第三方DLL有一些依赖关系(例如Infragistics2.Win.UltraWinChart.v10.3.dll
)。
该插件安装正常,但插件中嵌入的进程具有取决于UltraWinChart的UI。在为此过程创建GUI时,即使此文件与Infragistics2.Win.UltraWinChart.v10.3.dll
位于同一目录中,插件也会抛出一个无法加载MyCoolPlugin.dll
的异常。然后出现“此过程没有定义的描述或用户界面”-dialog。
如果我们将Infragistics2.Win.UltraWinChart.v10.3.dll
复制到probingPath
中定义的petrel.exe.config
中列出的目录,该插件可以正常工作。 plugin.xml
看起来正确,但没有引用依赖项。清单包含插件目录中每个文件的一个<File>
条目,包括Infragistics2.Win.UltraWinChart.v10.3.dll
。
为什么没有正确加载依赖项?
修改
我已经为我们遇到的问题找到了解决方法。通过在插件初始化(Initialize()
函数)上手动预加载依赖关系(通过文件名),我能够确保预先加载所有依赖关系。但是,我不确定这个解决方案是否稳定(我偶尔会在启动时崩溃)。我正在使用的代码是:
Assembly me = Assembly.GetExecutingAssembly();
FileInfo file = new FileInfo(me.Location);
foreach (FileInfo assembly in file.Directory.GetFiles("*.dll"))
{
try
{
Assembly.LoadFile(assembly.FullName);
}
catch (Exception e)
{
CoreLogger.Error(string.Format("Failed to load assembly {0}.", assembly.FullName), e);
}
}
您是否了解如何确保加载插件.NET程序集依赖项(外部依赖项,而不是模块依赖项)?您是否使用AppDomain.CurrentDomain.AssemblyResolve
- 事件来拦截负载故障? This answer显示了当所有其他方法都失败时,如何使用此事件从与执行程序集相同的文件夹加载程序集。我认为正确的方法是使用调用程序集(因为执行程序集可能是定义事件处理程序的程序集)。我还没有成功测试过这种解决方法。
请注意,我已经使用其他程序集进行了测试,以确保这不是Infragistics问题。
编辑2: 如前所述,插件DLL是由多个程序集组成的合并DLL。我使用this approach来确定直接依赖关系,而且似乎Infragistics不是其中之一。这可能是相关的吗?
答案 0 :(得分:1)
如果您选择使用AppDomain.CurrentDomain.AssemblyResolve事件,我会非常小心。在这种情况下,它可能会显着降低应用程序性能。你使用什么混淆工具。也许,最好的方法是看看为什么混淆会影响.NET中的ReferenceAssemblies调用。也许它是故意设计的。在这种情况下,您可能希望禁用混淆程序集的那一部分。
答案 1 :(得分:0)
这是一个奇怪的问题。我刚刚在我的插件上测试了一个类似的设置,它使用FMOD库来播放音乐。 fmod dll在部署列表中引用,它们显示在PIP的清单文件中,并且它们安装在插件安装目录中(在插件管理器定义的路径下)。插件运行@ runtime。也许与Petrel使用的infragistics库存在冲突?
答案 2 :(得分:0)
我认为这个问题与我们程序集的混淆有关。如果我们不对程序集进行模糊处理(从而将所有程序集合并为一个大程序集),一切正常。我猜这是因为Petrel正在加载插件程序集,检查引用程序集并递归加载依赖项。在这种情况下,这不起作用,因为并非所有程序集都列为参考程序集。
解决方法是在合并的程序集中包含引用程序集(Infragistics)。这似乎工作正常。但是,我想这并不总是可以接受的(例如对于LGPL许可的库)。
另一个,也许更好,apporach将听取AppDomain.CurrentDomain.AssemblyResolve
- 事件来拦截程序集加载错误。