public virtual PluginInfo GetInfo(string pluginFileName) { AppDomain domain = null; domain = AppDomain.CreateDomain("PluginLoaderBase.Probe"); Type t = this.GetType(); PluginLoaderBase loader = (PluginLoaderBase)domain.CreateInstanceFromAndUnwrap(t.Assembly.Location, t.FullName); PluginInfo info = loader.OnGetInfoWrapper(pluginFileName); AppDomain.Unload(domain); return(info); }
public virtual PluginInfoList Probe(string pluginFolderPath, SearchOption scanDeapth) { AppDomain domain = null; PluginInfoList infoList = new PluginInfoList(); domain = AppDomain.CreateDomain("PluginLoaderBase.Probe"); Type t = this.GetType(); PluginLoaderBase loader = (PluginLoaderBase)domain.CreateInstanceFromAndUnwrap(t.Assembly.Location, t.FullName); infoList = loader.OnProbeWrapper(pluginFolderPath, scanDeapth); AppDomain.Unload(domain); ProbeCompleteEventArgs probeCompleteArgs = new ProbeCompleteEventArgs(infoList); this.OnProbeComplete(probeCompleteArgs); return(infoList); }
public virtual void Load(string pluginFileName, PluginParameters args) { if (args == null) { args = new PluginParameters(); } AppDomainSetup domainSetup = new AppDomainSetup(); Assembly entryAsm = Assembly.GetEntryAssembly(); AssemblyProductAttribute[] atts = ((AssemblyProductAttribute[])entryAsm.GetCustomAttributes(typeof(AssemblyProductAttribute), false)); string productName = null; if (atts != null) { if (atts.Length > 0) { productName = atts[0].Product; } } if (String.IsNullOrEmpty(productName)) { domainSetup.ApplicationName = Path.GetFileNameWithoutExtension(entryAsm.Location); } else { domainSetup.ApplicationName = productName; } domainSetup.ConfigurationFile = Path.GetFileName(pluginFileName) + ".config"; domainSetup.ApplicationBase = Path.GetDirectoryName(pluginFileName); domainSetup.PrivateBinPath = "bin"; if (this.ShadowCopyEnabled) { domainSetup.ShadowCopyFiles = "true"; domainSetup.ShadowCopyDirectories = domainSetup.ApplicationBase + ";" + Path.Combine(domainSetup.ApplicationBase, "bin"); } PluginLoadingEventArgs loadingArgs = new PluginLoadingEventArgs(pluginFileName, domainSetup); this.OnPluginLoading(loadingArgs); if (!loadingArgs.Cancel) { AppDomain domain = null; domain = AppDomain.CreateDomain(loadingArgs.DomainSetup.ApplicationName, null, loadingArgs.DomainSetup); Type t = this.GetType(); PluginLoaderBase loader = (PluginLoaderBase)domain.CreateInstanceFromAndUnwrap(t.Assembly.Location, t.FullName); loader.AssemblyResolutionPaths = this.AssemblyResolutionPaths; PluginInfo info = loader.OnLoadWrapper(pluginFileName); if (info == null) { AppDomain.Unload(domain); } else { if (loader.IsPluginLoaded) { info.Domain = domain; this._currentInfoList.Add(info); PluginLoadedEventArgs pluginLoadedArgs = new PluginLoadedEventArgs(info); this.OnPluginLoaded(pluginLoadedArgs); PluginBase.ExecutionModes execMode = info.ExecutionMode; bool canExecute = false; if (!this.UseDefaultExecutionValidation) { canExecute = true; } else if (execMode == PluginBase.ExecutionModes.MultiInstance) { canExecute = true; } else if (execMode == PluginBase.ExecutionModes.Exclusive) { if (this._currentInfoList.Count == 1) { canExecute = true; } } else if (execMode == PluginBase.ExecutionModes.Singleton) { if (this.GetLoadedInstances(info.PluginFileName).Count == 1) { canExecute = true; } } else if (execMode == PluginBase.ExecutionModes.Custom) { canExecute = true; } if (canExecute) { info.Parameters = args; PluginExecutingEventArgs exeArgs = new PluginExecutingEventArgs(info); this.OnPluginExecuting(exeArgs); if (exeArgs.Cancel) { this.Unload(info, args, true, exeArgs.CancelReason); } else { info.Loader = loader; Thread pluginThread = new Thread(this.Execute); pluginThread.IsBackground = true; pluginThread.Start(info); } } else { this.Unload(info, args, true, null); } } else { AppDomain.Unload(domain); } } } }
void PluginLoader_ProbeComplete(object sender, PluginLoaderBase.ProbeCompleteEventArgs e) { Console.WriteInfo("Plugin probe completed with '" + Convert.ToString(e.InfoList.Count) + "' detections."); }
void PluginLoader_PluginUnloaded(object sender, PluginLoaderBase.PluginUnloadedEventArgs e) { if (e.ExecutionCancelled) { //Plugins can be denied execution by the PluginLoader object according to the specified value in PluginBase.ExecutionMode property if PluginLoaderBase.UseDefaultExecutionValidation is set to true. //This checks which execution modes prevented the plugin from being executed. if (e.Info.ExecutionMode == PluginBase.ExecutionModes.Exclusive) Console.WriteInfo("The plugin '" + e.Info.ToString() + "' was unloaded since it is intended to be executed exclusively. Please make sure no other plugin is executing and try again."); else if (e.Info.ExecutionMode == PluginBase.ExecutionModes.Singleton) Console.WriteInfo("The plugin '" + e.Info.ToString() + "' was unloaded since only one instance of it is intended to be executed at a time. Please make sure no other instance of the same plugin is executing and try again."); else if(e.ExecutionCancelledReason != null) Console.WriteInfo("The plugin '" + e.Info.ToString() + "' was unloaded due to the following reason: " + Convert.ToString(e.ExecutionCancelledReason)); else Console.WriteInfo("The plugin '" + e.Info.ToString() + "' was unloaded."); //If PluginLoaderBase.UseDefaultExecutionValidation is false, plugin execution validation and authorization can be handled via the PluginLoaderBase.PluginExecuting event. //The PluginLoaderBase.PluginExecutingEventArgs.Cancel property can be set to true to cancel execution of a plugin. //The PluginLoaderBase.PluginExecutingEventArgs.CancelReason property can be set to an object representing the reson for the cancellation. //The value set to PluginLoaderBase.PluginExecutingEventArgs.CancelReason in the PluginLoaderBase.PluginExecuting event handler can be accessed here using the e.ExecutionCancelledReason property } else { //Check if the plugin was unloaded due to an exception //The PluginException class wraps any unhandled plugin exception in a serializable wrapper. //The PluginException class also exposes all InnerExceptions of the actual exception through PluginException.InnerException as well //This makes sure that unhandled non-serializable exceptions do not cause unexpected AppDomain leaks in the main application. if (e.PluginException != null) Console.WriteException("The plugin '" + e.Info.ToString() + "' was unloaded due to unhandled exception: " + e.PluginException.ToString()); else { //Each plugin may return results in the form of a PluginParameters object exposed by the PluginLoaderBase.PluginUnloadedEventArgs.Results property //This object can be checked for values returned by the plugin like so, if (e.Results.Contains("ReturnValue")) Console.WriteInfo("The plugin '" + e.Info.ToString() + "' was unloaded successfully with the return value: " + Convert.ToString(e.Results.Get("ReturnValue"))); else Console.WriteInfo("The plugin '" + e.Info.ToString() + "' was unloaded successfully"); } } }
void PluginLoader_PluginLoading(object sender, PluginLoaderBase.PluginLoadingEventArgs e) { //You may make changes to the domain setup used to load the current plugin here i.e e.DomainSetup.ApplicationName, e.DomainSetup.CachePath, etc. //Or you can cancel the loading by setting e.Cancel = true Console.WriteInfo("Loading plugin from file '" + e.PluginFileName + "'..."); }
void PluginLoader_PluginLoaded(object sender, PluginLoaderBase.PluginLoadedEventArgs e) { Console.WriteInfo("Plugin '" + e.Info.ToString() + "' loaded successfully."); }
void PluginLoader_PluginExecuting(object sender, PluginLoaderBase.PluginExecutingEventArgs e) { //You can cancel the execution by setting e.Cancel = true //An object representing the reason for cancelling can be passed to the PluginLoaderBase.PluginUnloaded event by setting the e.CancelReason property if (e.Info.ExecutionMode == PluginBase.ExecutionModes.Custom) { e.Cancel = true; e.CancelReason = "Plugins with PluginBase.ExecutionMode set to Custom are not allowed"; } else Console.WriteInfo("Executing plugin '" + e.Info.ToString() + "'..."); }