/// <summary> /// Finds and returns the PluginAssembly in the specified list of type PluginAssembly whose FQN matches the specified FQN. /// </summary> /// <param name="fqn">The FQN of the desired PluginAssembly.</param> /// <returns> /// The PluginAssembly instance whose FQN matches the specified FQN, or the default PluginAssembly if not found. /// </returns> public IPluginAssembly FindPluginAssembly(string fqn) { logger.EnterMethod(xLogger.Params(fqn, new xLogger.ExcludedParam())); IPluginAssembly retVal = PluginAssemblies.Where(p => p.FQN == fqn).FirstOrDefault(); logger.ExitMethod(retVal); return(retVal); }
public static void RefreshPlugins() { // Read in the Assemblies to refresh string[] enabled = Config.Plugin.Enabled; List <PluginAssembly> asmsToRefresh = ReadAssemblyPaths().Select(path => { PluginAssembly asm; if (!GetAssembly(path, out asm)) { return(LoadAssembly(path)); } foreach (PluginInformation info in asm.PluginInformations .Where(info => enabled.Contains(info.PluginID))) { info.Enabled = true; asm.Enabled = true; } return(asm); }).ToList(); // Uninstall the currently installed Assemblies that aren't in the new list foreach (PluginAssembly asm in PluginAssemblies.Except(asmsToRefresh).ToList()) { UninstallPluginAssembly(asm); } // Make a list of PluginIDs that are disabled and disable them List <string> pidsToUnload = asmsToRefresh.SelectMany(asm => asm.PluginInformations) .Where(pi => !pi.Enabled).Select(pi => pi.PluginID).ToList(); foreach (string pid in pidsToUnload) // static { Plugin plugin; if (!dicStaticPluginInstances.TryGetValue(pid, out plugin)) { continue; } if (plugin.PluginInformation.PluginType == PluginType.Static) { plugin.Close(EndCode.Removed); } dicStaticPluginInstances.Remove(pid); } ClearIEncodingDetector(); // Refresh the existing ones. foreach (PluginAssembly pa in asmsToRefresh) { foreach (PluginInformation info in pa.PluginInformations) { if (info.Enabled) { LoadStaticInstance(info, pa); } } } InstanceManager.LocalTabBroadcast(tabbar => tabbar.pluginServer.RefreshPlugins()); }
/// <summary> /// Load all plugins<br/> /// Flow<br/> /// - Get plugin names from website configuration<br/> /// - Load plugin information from it's directory<br/> /// - Use roslyn compile service compile the source files to assembly<br/> /// - Load compiled assembly<br/> /// - Register types in assembly to IoC container<br/> /// Attention<br/> /// - IPlugin will not initliaze here because we may need initialize database before<br/> /// you should invoke IPlugin manually after calling this method<br/> /// 加载所有插件<br/> /// 流程<br/> /// - 从网站配置获取插件名称列表<br/> /// - 从插件目录加载插件信息<br/> /// - 使用roslyn编译服务编译插件源代码到程序集<br/> /// - 加载编译后的程序集<br/> /// - 注册程序集中的类型到IoC容器<br/> /// 注意<br/> /// - 插件不会在这里初始化, 因为我们可能需要在这之前初始化数据库<br/> /// 你需要在调用这个函数后手动调用IPlugin接口<br/> /// </summary> internal protected virtual void Initialize() { var configManager = Application.Ioc.Resolve <WebsiteConfigManager>(); var pathManager = Application.Ioc.Resolve <LocalPathManager>(); Plugins.Clear(); PluginAssemblies.Clear(); // Get plugin names from website configuration var pluginDirectories = pathManager.GetPluginDirectories(); foreach (var pluginName in configManager.WebsiteConfig.Plugins) { var dir = pluginDirectories .Select(p => PathUtils.SecureCombine(p, pluginName)) .FirstOrDefault(p => Directory.Exists(p)); if (dir == null) { throw new DirectoryNotFoundException($"Plugin directory of {pluginName} not found"); } var info = PluginInfo.FromDirectory(dir); if (ShouldLoadPlugin(info)) { Plugins.Add(info); } } // Load plugins var assemblyLoader = Application.Ioc.Resolve <IAssemblyLoader>(); foreach (var plugin in Plugins) { // Compile plugin plugin.Compile(); // Load compiled assembly, some plugin may not have an assembly var assemblyPath = plugin.AssemblyPath(); if (File.Exists(assemblyPath)) { // .NET will cache assembly by path, so if assembly contents changed // after plugin recompile, LoadFile will still use the old assembly, // we should load bytes instead of path to avoid caching. var assembly = assemblyLoader.Load(File.ReadAllBytes(assemblyPath)); plugin.Assembly = assembly; PluginAssemblies.Add(assembly); PluginAssemblyPathes.Add(assemblyPath); } } // Register types in assembly to IoC container // Only public types will be registered foreach (var assembly in PluginAssemblies) { var types = assembly.GetTypes().Where(t => t.IsPublic); Application.Ioc.RegisterExports(types); } }
public Host( IOmniSharpEnvironment environment, ISharedTextWriter sharedTextWriter, PluginAssemblies commandLinePlugins, int serverPort, string serverInterface) { _environment = environment; _sharedTextWriter = sharedTextWriter; _commandLinePlugins = commandLinePlugins; _serverPort = serverPort; _serverInterface = serverInterface; }
static int Main(string[] args) => HostHelpers.Start(() => { var application = new HttpCommandLineApplication(); application.OnExecute(() => { var environment = application.CreateEnvironment(); Configuration.ZeroBasedIndices = application.ZeroBasedIndices; var writer = new SharedTextWriter(Console.Out); var commandLinePlugins = new PluginAssemblies(application.Plugin); var host = new Host(environment, writer, commandLinePlugins, application.Port, application.Interface); host.Start(); return(0); }); return(application.Execute(args)); });
/// <summary> /// Gets all loaded assemblies in the app domain or that the plugin manager knows about /// </summary> /// <returns>A list of assemblies that are in the app domain or that the plugin manager knows about</returns> public virtual List <Assembly> GetLoadedAssemblies() { // Add plugin assemblies var output = PluginAssemblies.ToList(); // Add current assembly var currentAssembly = typeof(PluginManager).GetTypeInfo().Assembly; if (!output.Contains(currentAssembly)) { output.Add(currentAssembly); } // Add core plugin assembly if (!output.Contains(CorePluginAssembly)) { output.Add(CorePluginAssembly); } return(output); }
private void AddAssembly(CrmPluginAssembly crmPluginAssembly) { PluginAssemblies.Add(crmPluginAssembly); }
public Startup(IOmniSharpEnvironment environment, IEventEmitter eventEmitter, PluginAssemblies commandLinePlugins) { _environment = environment; _eventEmitter = eventEmitter; _commandLinePlugins = commandLinePlugins; }
/// <summary> /// Loads the given Core plugin and any other available plugins, if supported by the environment. /// </summary> /// <param name="core">The core plugin that controls the environment.</param> /// <remarks> /// Misc things this function does: /// - Delete files scheduled for deletion /// - Install pending extensions /// </remarks> /// <exception cref="ArgumentNullException">Thrown if <paramref name="core"/> is null.</exception> public virtual async Task LoadCore(CoreSkyEditorPlugin core) { if (core == null) { throw new ArgumentNullException(nameof(core)); } // Load providers CurrentFileSystem = core.GetFileSystem(); CurrentSettingsProvider = core.GetSettingsProvider(this); CurrentConsoleProvider = core.GetConsoleProvider(); // Delete files and directories scheduled for deletion await DeleteScheduledFiles(CurrentSettingsProvider, CurrentFileSystem); // Install pending extensions ExtensionDirectory = core.GetExtensionDirectory(); await ExtensionHelper.InstallPendingExtensions(ExtensionDirectory, this); // Load the provided core CorePluginAssembly = core.GetType().GetTypeInfo().Assembly; Plugins.Add(core); core.Load(this); // Load plugins, if enabled if (core.IsPluginLoadingEnabled()) { // Get the paths of all plugins to be loaded var supportedPlugins = GetPluginPaths(); // Load the plugin assemblies foreach (var item in supportedPlugins) { try { var assemblyActual = core.LoadAssembly(item); if (assemblyActual != null) { PluginAssemblies.Add(assemblyActual); foreach (var plg in assemblyActual.DefinedTypes.Where((x) => ReflectionHelpers.IsOfType(x, typeof(SkyEditorPlugin).GetTypeInfo()) && this.CanCreateInstance(x))) { Plugins.Add(this.CreateInstance(plg) as SkyEditorPlugin); } } } catch (FileLoadException) { // The assembly is a bad assembly. We can continue loading plugins, but not with this FailedPluginLoads.Add(item); } catch (BadImageFormatException) { // The assembly is a bad assembly. We can continue loading plugins, but not with this FailedPluginLoads.Add(item); } catch (NotSupportedException) { // The current environment does not support loading assemblies this way. // Abort dynamic assembly loading break; } } } // Load logical plugins PluginsLoading?.Invoke(this, new EventArgs()); var coreType = core.GetType(); foreach (var item in Plugins.Where(p => p.GetType() != core.GetType())) { item.Load(this); } // Load dependant plugins while (DependantPluginLoadingQueue.Count > 0) { var item = DependantPluginLoadingQueue.Dequeue(); var pluginType = item.GetType(); // Determine if it has already been loaded if (!Plugins.Where((x) => x.GetType() == pluginType).Any()) { // Add the plugin Plugins.Add(item); // Add the assembly if it hasn't been added already var pluginAssembly = pluginType.GetTypeInfo().Assembly; if (!PluginAssemblies.Contains(pluginAssembly)) { PluginAssemblies.Add(pluginAssembly); } // Load the plugin item.Load(this); } } // Use reflection to fill the type registry if (core.IsCorePluginAssemblyDynamicTypeLoadEnabled()) { LoadTypes(CorePluginAssembly); } if (core.IsExtraPluginAssemblyDynamicTypeLoadEnabled()) { foreach (var item in PluginAssemblies) { LoadTypes(item); } } PluginLoadComplete?.Invoke(this, new EventArgs()); }