public List <PossiblyPluginFileInfo> GetAllPluginFiles() { var arAllPlugins = new List <PossiblyPluginFileInfo>(); var pluginnames = new HashSet <string>(); // Discover plugin files, skip disabled foreach (PluginFolder folder in PluginFolders) { foreach (PossiblyPluginFileInfo file in folder.GetPluginFiles()) { // Higher priority goes first, ignore subsequent duplicates (applies to plugins only) // Non-plugins are always added if ((!file.IsPlugin) || (pluginnames.Add(Path.GetFileNameWithoutExtension(file.File.FullName)))) { arAllPlugins.Add(file); } else { // Duplicate PossiblyPluginFileInfo fileNot = PossiblyPluginFileInfo.CreateNo(file.Folder, file.File, "There was another plugin with the same assembly name in the same or a higher-priority folder."); arAllPlugins.Add(fileNot); Trace.WriteLine(fileNot.ToString(), "Plugin.Loader"); } } } return(arAllPlugins); }
/// <summary> /// Loads the plugin assembly and creates one or more <see cref="IPlugin"/> types from it. /// </summary> private bool LoadPlugins_LoadFile([NotNull] PossiblyPluginFileInfo file, [NotNull] out string sError) { if (file.File == null) { throw new ArgumentNullException("file"); } // Here the plugin DLL is loaded by CLR // IPlugin instances are searched for, primary plugins checked for authenticity if (!IsOmeaPluginDll(file.File, out sError)) { return(false); } Trace.WriteLine(string.Format("Loading plugin file “{0}”.", file.File.FullName), "Plugin.Loader"); // Get the types from the assembly, to look for plugins Assembly assembly; Type[] types; try { assembly = LoadPluginAssembly(file.File); types = assembly.GetExportedTypes(); } catch (Exception ex) { sError = ex.Message; return(false); } // Load each IPlugin int nLoadedTypes = 0; foreach (Type type in types) { if (IsOmeaPluginType(type)) { string sTypeError; if (LoadPlugins_LoadFile_LoadType(type, file, out sTypeError)) { nLoadedTypes++; } else { sError += sTypeError + " "; } } } // Any plugins loaded? Read declarative XML config if (nLoadedTypes > 0) { _arAssembliesToLoadXmlConfigFrom.Add(assembly); } // If we have picked the DLL as a plugin, then it must have at least one IPlugin type return(nLoadedTypes > 0); }
/// <summary> /// Tries creating and registering the plugin instance from the given class. /// </summary> private bool LoadPlugins_LoadFile_LoadType([NotNull] Type type, PossiblyPluginFileInfo file, out string sError) { if (type == null) { throw new ArgumentNullException("type"); } // Duplicate with someone? if (!_hashLoadedPluginTypes.Add(type.FullName)) { sError = string.Format("The plugin class “{0}” has already been loaded from another assembly.", type.FullName); return(false); } // Create and register try { var plugin = (IPlugin)Activator.CreateInstance(type); plugin.Register(); _plugins.Add(plugin); _mapPluginFileInfo.Add(plugin, file); } catch (CancelStartupException) // Special exception to abort the startup { throw; } catch (Exception ex) { #if DEBUG Core.ReportException(ex, false); #endif sError = "The plugin failed to register itself. " + ex.Message; return(false); } sError = ""; return(true); }
public IEnumerable <PossiblyPluginFileInfo> GetPluginFiles() { if (!Directory.Exists) { return new PossiblyPluginFileInfo[] {} } ; // List of folders to check var directories = new List <DirectoryInfo> { Directory }; // In non-primary folders, also check subfolders: complex plugins might not want to mix their files up with others if (!IsPrimary) { foreach (DirectoryInfo directory in Directory.GetDirectories()) { if ((directory.Attributes & FileAttributes.Hidden) == 0) { directories.Add(directory); } } } var files = new List <PossiblyPluginFileInfo>(); PossiblyPluginFileInfo pluginfileinfo; // Look for the regex-matching files foreach (DirectoryInfo directory in directories) { foreach (FileInfo file in directory.GetFiles()) { if (!_arPluginAssemblyExtensions.Contains(file.Extension.Trim('.'))) { // Note: do not report such items at all, to avoid noise Trace.WriteLine(PossiblyPluginFileInfo.CreateNo(this, file, "File extension mismatch, assembly expected."), "Plugin.Loader"); continue; } if ((file.Attributes & FileAttributes.Hidden) != 0) // Skip hidden files { pluginfileinfo = PossiblyPluginFileInfo.CreateNo(this, file, "The file is hidden."); } else if (!RegexOmeaPluginFile.IsMatch(file.Name)) // Apply file name filter { pluginfileinfo = PossiblyPluginFileInfo.CreateNo(this, file, "The file name does not include “OmeaPlugin”."); } else { pluginfileinfo = PossiblyPluginFileInfo.CreateYes(this, file); } // Note: here we do not check for IPlugin types and such, as it will cause loading the DLLs without the progress (we don't know the total count yet) // Pick files.Add(pluginfileinfo); Trace.WriteLine(pluginfileinfo.ToString(), "Plugin.Loader"); } } return(files); }