/// <summary> /// Creates an instance of a <see cref="Plugin"/> class to be inserted into the database. /// </summary> /// <param name="assembly">The assembly of the plug-in.</param> /// <param name="plugin">The initialized plug-in.</param> /// <param name="fileNameFull">The full file name of the plug-in assembly.</param> /// <returns>A <see cref="Plugin"/> class instance based on the given arguments.</returns> public static Plugin FromPlugin(Assembly assembly, IScriptNotepadPlugin plugin, string fileNameFull) { try { // create a result based on the given parameters.. var result = new Plugin { FileNameFull = fileNameFull, FileName = Path.GetFileName(fileNameFull), FilePath = Path.GetDirectoryName(fileNameFull), PluginName = plugin.PluginName, PluginDescription = plugin.PluginDescription, IsActive = true, PluginInstalled = DateTime.Now, PluginVersion = VersionStringFromAssembly(assembly), }; // set the version for the plug-in.. AssemblyVersion.SetPluginUpdated(result, assembly); // return the result.. return(result); } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex); return(null); } }
/// <summary> /// Initializes the given plug-in instance. /// </summary> /// <param name="plugin">The plug-in instance to initialize.</param> /// <param name="onRequestActiveDocument">The event provided by the hosting software (ScriptNotepad) to request for the active document within the software.</param> /// <param name="onRequestAllDocuments">The event provided by the hosting software (ScriptNotepad) to request for all open documents within the software.</param> /// <param name="onPluginException">The event provided by the hosting software (ScriptNotepad) for error reporting.</param> /// <param name="mainMenu">The <see cref="MenuStrip"/> which is the main menu of the hosting software (ScriptNotepad).</param> /// <param name="pluginMenuStrip">The <see cref="ToolStripMenuItem"/> which is the plug-in menu in the hosting software (ScriptNotepad).</param> /// <param name="sessionName">The name of the current session in the hosting software (ScriptNotepad).</param> /// <param name="formMain">A reference to the main form of the hosting software (ScriptNotepad).</param> /// <returns>True if the operation was successful; otherwise false.</returns> public static bool InitializePlugin(IScriptNotepadPlugin plugin, OnRequestActiveDocument onRequestActiveDocument, OnRequestAllDocuments onRequestAllDocuments, OnPluginException onPluginException, MenuStrip mainMenu, ToolStripMenuItem pluginMenuStrip, string sessionName, FormMain formMain ) { try { // initialize the plug-in.. plugin.Initialize(onRequestActiveDocument, onRequestAllDocuments, onPluginException, mainMenu, pluginMenuStrip, sessionName, formMain); return(true); // success.. } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex, null, null, "PluginInitializer.InitializePlugin_#1"); return(false); // fail.. } }
/// <summary> /// Tries to loads a plug-in with a given file name. /// </summary> /// <param name="fileName">Name of the file containing the plug-in assembly.</param> /// <returns>A tuple containing the assembly and an instance created for the plug-in implementing /// the <see cref="IScriptNotepadPlugin"/> interface along with the assembly file name if successful; /// otherwise the resulting value contains some null values.</returns> public static (Assembly assembly, IScriptNotepadPlugin Plugin, string FileName) LoadPlugin(string fileName) { try { // load the found assembly.. Assembly assembly = Assembly.LoadFile(fileName); foreach (Type type in assembly.GetTypes()) { // again keep on trying.. try { // check the validity of the found type.. if (typeof(IScriptNotepadPlugin).IsAssignableFrom(type) && typeof(ScriptNotepadPlugin).IsAssignableFrom(type)) { // create an instance of the class implementing the IScriptNotepadPlugin interface.. IScriptNotepadPlugin plugin = (IScriptNotepadPlugin)Activator.CreateInstance(type); return(assembly, plugin, fileName); } } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex, assembly, fileName, "PluginInitializer.LoadPlugin_#1"); // indicate a failure in the result as well.. return(assembly, null, fileName); } } // a class type implementing the IScriptNotepadPlugin interface wasn't found.. return(assembly, null, fileName); } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex, null, fileName, "PluginInitializer.LoadPlugin_#2"); return(null, null, fileName); } }
/// <summary> /// Updates the plug-in entry data. /// </summary> /// <param name="pluginEntry">The plug-in entry <see cref="Plugin"/>.</param> /// <param name="assembly">The assembly of the plug-in.</param> /// <param name="plugin">The initialized plug-in.</param> /// <param name="fileNameFull">The full file name of the plug-in assembly.</param> /// <returns>An updated <see cref="Plugin"/> class instance based on the given arguments.</returns> public static Plugin UpdateFromPlugin(Plugin pluginEntry, Assembly assembly, IScriptNotepadPlugin plugin, string fileNameFull) { try { pluginEntry.FileNameFull = fileNameFull; pluginEntry.FileName = Path.GetFileName(fileNameFull); pluginEntry.FilePath = Path.GetDirectoryName(fileNameFull); pluginEntry.PluginName = plugin.PluginName; pluginEntry.PluginDescription = plugin.PluginDescription; // set the version for the plug-in.. AssemblyVersion.SetPluginUpdated(pluginEntry, assembly); return(pluginEntry); } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex); return(pluginEntry); } }
/// <summary> /// Gets the plug-in assemblies for the software. /// </summary> /// <param name="directory">The directory to search the plug-in assemblies from.</param> /// <returns>A collection of tuples containing the information of the found assemblies.</returns> public static IEnumerable <(Assembly Assembly, string Path, bool IsValid)> GetPluginAssemblies(string directory) { // create a list for the results.. List <(Assembly Assembly, string Path, bool IsValid)> result = new List <(Assembly Assembly, string Path, bool IsValid)>(); try { ExceptionLogger.LogMessage($"Plugin path, get: '{directory}'"); // recurse the plug-in path.. string[] assemblies = Directory.GetFiles(directory, "*.dll", SearchOption.AllDirectories); // loop through the results.. foreach (string assemblyFile in assemblies) { // ReSharper disable once CommentTypo // some other files (.dll_blaa) might come with the *.dll mask.. if (!String.Equals(Path.GetExtension(assemblyFile), ".dll", StringComparison.InvariantCultureIgnoreCase)) { // ..in that case do continue.. continue; } // this might also fail so try.. try { // load the found assembly.. Assembly assembly = Assembly.LoadFile(assemblyFile); foreach (Type type in assembly.GetTypes()) { // again keep on trying.. try { // check the validity of the found type.. if (typeof(IScriptNotepadPlugin).IsAssignableFrom(type) && typeof(ScriptNotepadPlugin).IsAssignableFrom(type)) { // create an instance of the class implementing the IScriptNotepadPlugin interface.. IScriptNotepadPlugin plugin = (IScriptNotepadPlugin)Activator.CreateInstance(type); // the IScriptNotepadPlugin is also disposable, so do dispose of it.. using (plugin) { if (!result.Exists(f => f.Path != null && Path.GetFileName(f.Path) == Path.GetFileName(assemblyFile))) { result.Add((assembly, assemblyFile, true)); } } } } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex, assembly, assemblyFile); // indicate a failure in the result as well.. if (!result.Exists(f => f.Path != null && Path.GetFileName(f.Path) == Path.GetFileName(assemblyFile))) { result.Add((assembly, assemblyFile, false)); } } } } catch (Exception ex) { // log the exception.. ExceptionLogAction?.Invoke(ex, null, assemblyFile); // indicate a failure in the result as well.. if (!result.Exists(f => f.Path != null && Path.GetFileName(f.Path) == Path.GetFileName(assemblyFile))) { result.Add((null, assemblyFile, false)); } } } } // a failure.. catch (Exception ex) { // ..so do log it.. ExceptionLogAction?.Invoke(ex, null, null); } // return the result.. return(result); }