/// <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);
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        /// <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);
            }
        }
Beispiel #4
0
 public Host(
     IOmniSharpEnvironment environment,
     ISharedTextWriter sharedTextWriter,
     PluginAssemblies commandLinePlugins,
     int serverPort,
     string serverInterface)
 {
     _environment        = environment;
     _sharedTextWriter   = sharedTextWriter;
     _commandLinePlugins = commandLinePlugins;
     _serverPort         = serverPort;
     _serverInterface    = serverInterface;
 }
Beispiel #5
0
        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));
        });
Beispiel #6
0
        /// <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);
        }
Beispiel #7
0
 private void AddAssembly(CrmPluginAssembly crmPluginAssembly)
 {
     PluginAssemblies.Add(crmPluginAssembly);
 }
Beispiel #8
0
 public Startup(IOmniSharpEnvironment environment, IEventEmitter eventEmitter, PluginAssemblies commandLinePlugins)
 {
     _environment        = environment;
     _eventEmitter       = eventEmitter;
     _commandLinePlugins = commandLinePlugins;
 }
Beispiel #9
0
        /// <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());
        }