larsmoa
larsmoa

Reputation: 12932

Petrel 2011 plugins not able to load dependent assemblies from the installation folder

We're building a PIP-installer for our plugin. The plugin consists of one module in one DLL, lets call it MyCoolPlugin.dll (actually, this DLL consists of several merged DLLs). In addition the plugin has a few dependencies to third party DLLs (e.g. Infragistics2.Win.UltraWinChart.v10.3.dll).

The plugin installs fine, but the process embedded in the plugin has an UI depending on UltraWinChart. When creating the GUI for this process the plugin throws an exception about not being able to load Infragistics2.Win.UltraWinChart.v10.3.dll even though this file resides in the same directory as MyCoolPlugin.dll. The "This process does not have a defined description or user interface"-dialog then appears.

If we copy Infragistics2.Win.UltraWinChart.v10.3.dll to a directory listed in the probingPath defined in petrel.exe.config the plugin works fine. The plugin.xml looks correct, but has no references to the dependencies. The manifest contains one <File> entry for each file in the plugin directory, including Infragistics2.Win.UltraWinChart.v10.3.dll.

Why isn't the dependencies loaded correctly?

EDIT:

I've come up with a workaround for the problems we're seeing. By manually preloading dependencies (by filenames) on plugin initialization (the Initialize() function) I'm able to ensure that all dependencies are pre-loaded. However, I'm not sure if this solution is stable (I get occasional crashes on startup). The code I'm using is:

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);
    }
}

Do you have any details on how you ensure plugin .NET assembly dependencies are loaded (external dependencies, not module dependencies)? Are you using the AppDomain.CurrentDomain.AssemblyResolve-event to intercept load failures? This answer shows how to use this event to load assemblies from the same folder as the executing assembly when all else fails. I think that the correct approach would be to use the calling assembly instead (as the executing assembly probably will be the assembly in which the event handler is defined). I haven't successfully tested this workaround yet.

Note that I've tested with other assemblies to ensure that this isn't an Infragistics-issue.

Edit 2: As stated in the earlier, the plugin DLL is a merged DLL consisting of several assemblies. I've used this approach to determine the direct dependencies, and it seems Infragistics isn't one of them. Could this be of relevance?

Upvotes: 2

Views: 939

Answers (3)

user829916
user829916

Reputation: 49

I would be very careful if you choose to work with the AppDomain.CurrentDomain.AssemblyResolve event. It could significantly degrade the application performance in this case. What obfuscation tools are you using. Perhaps, the best way is to see why obfuscation would affect the ReferenceAssemblies call in .NET. Perhaps it is intentionally by design. In this case, you may want to disable obfuscating that part of your assembly.

Upvotes: 1

larsmoa
larsmoa

Reputation: 12932

I think the issue is related to obfuscation of our assembly. If we do not obfuscate the assembly (and hence merge all assemblies into one big assembly) everything works fine. I'm guessing that this is because Petrel is loading plugin assemblies, checking the reference assemblies and loading dependencies recursively. This won't work in this case as not all assemblies are listed as reference assemblies.

A workaround for this is to include the reference assemblies (Infragistics) in the merged assembly. This seems to work fine. However, I guess this isn't always acceptable (e.g. for LGPL licensed libraries).

Another, maybe better, apporach would be to listen to the AppDomain.CurrentDomain.AssemblyResolve-event to intercept assembly loading errors.

Upvotes: 0

Gaute Gamst
Gaute Gamst

Reputation: 128

This is a strange issue. I have just tested a similar set-up on my plug-in, which uses an FMOD library to play music. The fmod dll's are referenced in the deploy list, they show up in the manifest file in the PIP, and they are installed in the plug-in install directory (underneath the path defined by the plug-in manager). The plug-in works @ runtime. Maybe there is a conflict with the infragistics libraries that Petrel uses?

Upvotes: 0

Related Questions