开发者

Application Specific Paths for DLL Loading when DLL is loaded dynamically

开发者 https://www.devze.com 2022-12-23 14:54 出处:网络
I am building a program that uses a very simple plugin system. This is the code I\'m using to load the possible plugins:

I am building a program that uses a very simple plugin system. This is the code I'm using to load the possible plugins:

  public interface IPlugin
  {
    string Name { get; }
    string Description { get; }
    bool Execute(System.Windows.Forms.IWin32Window parent);
  }


  private void loadPlugins()
  {
    int idx = 0;
    string[] pluginFolders = getPluginFolders();
    Array.ForEach(pluginFolders, folder =>
    {
      string[] pluginFiles = getPluginFiles(folder);
      Array.ForEach(pluginFiles, file =>
      {
        try
        {
          System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(file);
          Array.ForEach(assembly.GetTypes(), type =>
          {
            if(type.GetInterface("PluginExecutor.IPlugin") != null)
            {
              IPlugin plugin = assembly.CreateInstance(type.ToString()) as IPlugin;
              if(plugin != null)
                lista.Add(new PluginItem(plugin.Name, plugin.Description, file, plugin));
            }
          });
        }
        catch(Exception) { }
      });
    });
  }

When the user selects a particular plugin from the list, I launch the plugin's Execute method. So far, so good! As you can see the plugins are loaded from a folder, and within the folder are several dll's that are needed but the plugin. My problem is that I can't get the plugin to 'see' the dlls, it just searches the launching applications startup folder, but not the folder where the plugin was loaded from.

I have tried several methods: 1. Changing the Current Directory to the plugins folder. 2. Using an inter-op call to SetDllDirectory 3. Adding an entry in the registry to point to a folder where I want it to look (see code below)

None of these methods work. What am I missing? As I load the dll plugin dynamically, it does not seem to obey any of the above mentioned methods. What else can I try?

Regards, MartinH.

//HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths
Microsoft.Win32.RegistryKey appPaths = Microsoft.Win32.Registry.LocalMachine.CreateSubKey(
  string.Format(
    @"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\{0}",
     System.IO.Path.Get开发者_高级运维FileName(Application.ExecutablePath)),
  Microsoft.Win32.RegistryKeyPermissionCheck.ReadWriteSubTree);
appPaths.SetValue(string.Empty, Application.ExecutablePath);
object path = appPaths.GetValue("Path");
if(path == null)
  appPaths.SetValue("Path", System.IO.Path.GetDirectoryName(pluginItem.FileName));
else
{
  string strPath = string.Format("{0};{1}", path, System.IO.Path.GetDirectoryName(pluginItem.FileName));
  appPaths.SetValue("Path", strPath);
}
appPaths.Flush();


Use Assembly.LoadFrom not Assembly.LoadFile


Whenever I dynamically load plugins like this, I usually create an app domain and load the assembly in the new app domain. When creating an app domain, you can specify the base directory. Dependent assemblies will be loaded from this base directory.

0

精彩评论

暂无评论...
验证码 换一张
取 消