Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
11/23/09 20:27:43 (15 years ago)
Author:
gkronber
Message:

Implemented changes as requested by swagner. #799

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/PluginInfrastructure Refactoring/HeuristicLab.PluginInfrastructure/Manager/PluginValidator.cs

    r2517 r2527  
    2727using System.Diagnostics;
    2828using System.Linq;
     29using System.Security;
    2930
    3031
     
    8687      pluginDependencies.Clear();
    8788
    88       IEnumerable<Assembly> reflectionOnlyAssemblies = ReflectionOnlyLoadDlls();
     89      IEnumerable<Assembly> reflectionOnlyAssemblies = ReflectionOnlyLoadDlls(PluginDir);
    8990      IEnumerable<PluginDescription> pluginDescriptions = GatherPluginDescriptions(reflectionOnlyAssemblies);
    9091      CheckPluginFiles(pluginDescriptions);
     92
     93      CheckPluginAssemblies(pluginDescriptions);
    9194
    9295      // a full list of plugin descriptions is available now we can build the dependency tree
     
    137140    }
    138141
    139     private IEnumerable<Assembly> ReflectionOnlyLoadDlls() {
     142    private static IEnumerable<Assembly> ReflectionOnlyLoadDlls(string baseDir) {
    140143      List<Assembly> assemblies = new List<Assembly>();
     144      // recursively load .dll files in subdirectories
     145      foreach (string dirName in Directory.GetDirectories(baseDir)) {
     146        assemblies.AddRange(ReflectionOnlyLoadDlls(dirName));
     147      }
    141148      // try to load each .dll file in the plugin directory into the reflection only context
    142       foreach (string filename in Directory.GetFiles(PluginDir, "*.dll")) {
     149      foreach (string filename in Directory.GetFiles(baseDir, "*.dll")) {
    143150        try {
    144151          assemblies.Add(Assembly.ReflectionOnlyLoadFrom(filename));
    145152        }
    146153        catch (BadImageFormatException) { } // just ignore the case that the .dll file is not a CLR assembly (e.g. a native dll)
     154        catch (FileLoadException) { }
     155        catch (SecurityException) { }
    147156      }
    148157      return assemblies;
    149158    }
     159
     160    /// <summary>
     161    /// Checks if all plugin assemblies can be loaded. If an assembly can't be loaded the plugin is disabled.
     162    /// </summary>
     163    /// <param name="pluginDescriptions"></param>
     164    private void CheckPluginAssemblies(IEnumerable<PluginDescription> pluginDescriptions) {
     165      foreach (var desc in pluginDescriptions.Where(x => x.PluginState != PluginState.Disabled)) {
     166        try {
     167          foreach (var asm in desc.Assemblies) {
     168            Assembly.ReflectionOnlyLoadFrom(asm);
     169          }
     170        }
     171        catch (BadImageFormatException) {
     172          // disable the plugin
     173          desc.Disable();
     174        }
     175        catch (FileNotFoundException) {
     176          // disable the plugin
     177          desc.Disable();
     178        }
     179        catch (FileLoadException) {
     180          // disable the plugin
     181          desc.Disable();
     182        }
     183        catch (ArgumentException) {
     184          // disable the plugin
     185          desc.Disable();
     186        }
     187        catch (SecurityException) {
     188          // disable the plugin
     189          desc.Disable();
     190        }
     191      }
     192    }
     193
    150194
    151195    // find all types implementing IPlugin in the reflectionOnlyAssemblies and create a list of plugin descriptions
     
    158202        // of the current assembly is missing.
    159203        try {
    160           foreach (Type t in assembly.GetExportedTypes()) {
    161             // if there is a type that implements IPlugin
    162             // use AssemblyQualifiedName to compare the types because we can't directly
    163             // compare ReflectionOnly types and Execution types
    164             if (!t.IsAbstract &&
    165                 t.GetInterfaces().Any(x => x.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName)) {
    166               // fetch the attributes of the IPlugin type
    167               pluginDescriptions.Add(GetPluginDescription(t));
    168             }
    169           }
     204          // if there is a type that implements IPlugin
     205          // use AssemblyQualifiedName to compare the types because we can't directly
     206          // compare ReflectionOnly types and execution types
     207          var assemblyPluginDescriptions = from t in assembly.GetExportedTypes()
     208                                           where !t.IsAbstract && t.GetInterfaces().Any(x => x.AssemblyQualifiedName == typeof(IPlugin).AssemblyQualifiedName)
     209                                           select GetPluginDescription(t);
     210          pluginDescriptions.AddRange(assemblyPluginDescriptions);
    170211        }
    171212        // ignore exceptions. Just don't yield a plugin description when an exception is thrown
     
    206247          string pluginFileName = (string)attributeData.ConstructorArguments[0].Value;
    207248          PluginFileType fileType = (PluginFileType)attributeData.ConstructorArguments[1].Value;
    208           pluginFiles.Add(Path.Combine(PluginDir, pluginFileName));
     249          pluginFiles.Add(Path.GetFullPath(Path.Combine(PluginDir, pluginFileName)));
    209250          if (fileType == PluginFileType.Assembly) {
    210             pluginAssemblies.Add(Path.Combine(PluginDir, pluginFileName));
     251            pluginAssemblies.Add(Path.GetFullPath(Path.Combine(PluginDir, pluginFileName)));
    211252          }
    212253        }
     
    302343
    303344    // checks if all declared plugin files are actually available and disables plugins with missing files
    304     private static void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
     345    private void CheckPluginFiles(IEnumerable<PluginDescription> pluginDescriptions) {
    305346      foreach (PluginDescription desc in pluginDescriptions) {
    306347        if (!CheckPluginFiles(desc)) {
     
    310351    }
    311352
    312     private static bool CheckPluginFiles(PluginDescription pluginDescription) {
     353    private bool CheckPluginFiles(PluginDescription pluginDescription) {
    313354      foreach (string filename in pluginDescription.Files) {
    314         if (!File.Exists(filename)) {
     355        if (!FileLiesInDirectory(PluginDir, filename) ||
     356          !File.Exists(filename)) {
    315357          return false;
    316358        }
    317359      }
    318360      return true;
     361    }
     362
     363    private static bool FileLiesInDirectory(string dir, string fileName) {
     364      var basePath = Path.GetFullPath(dir);
     365      return Path.GetFullPath(fileName).StartsWith(basePath);
    319366    }
    320367
Note: See TracChangeset for help on using the changeset viewer.