动态加载DLL时DLL加载的特定于应用程序的路径

时间:2010-03-22 18:37:44

标签: c# .net

我正在构建一个使用非常简单的插件系统的程序。这是我用来加载可能的插件的代码:

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

当用户从列表中选择特定插件时,我启动插件的Execute方法。到现在为止还挺好!正如您所看到的,插件是从文件夹加载的,并且在该文件夹中有几个dll是需要的插件。我的问题是我无法让插件“看到”dll,它只是搜索启动的应用程序启动文件夹,而不是搜索加载插件的文件夹。

我尝试了几种方法: 1.将当前目录更改为plugins文件夹。 2.使用对SetDllDirectory的操作间调用 3.在注册表中添加一个条目以指向我希望它看的文件夹(参见下面的代码)

这些方法都不起作用。我错过了什么?当我动态加载dll插件时,它似乎不遵守任何上述方法。我还能尝试什么?

此致 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.GetFileName(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();

2 个答案:

答案 0 :(得分:2)

使用Assembly.LoadFrom而不是Assembly.LoadFile

答案 1 :(得分:2)

每当我动态加载这样的插件时,我通常会创建一个app域并在新的app域中加载程序集。创建应用程序域时,可以指定基目录。将从此基本目录加载从属程序集。