/// <summary>Loads the plug-in assembly types.</summary> /// <param name="pluginLocations">The plug-in locations.</param> /// <returns>A collection of the plug-in assembly types.</returns> /// <exception cref="PluginException">An error occurred attempting to load the plug-in assembly types.</exception> public PluginTypeCollection LoadPluginAssemblyTypes(IReadOnlyList <PluginLocation> pluginLocations) { PluginTypeCollection pluginTypeCollection = new PluginTypeCollection(); if (pluginLocations == null || pluginLocations.Count == 0) { return(pluginTypeCollection); } foreach (PluginLocation location in pluginLocations) { try { string pluginName = location.AssemblyLocation; string symbolDatabaseName = location.SymbolsDatabaseLocation; // read assembly information Assembly pluginAssembly; if (string.IsNullOrWhiteSpace(symbolDatabaseName)) { pluginAssembly = Assembly.Load(pluginName); } else { byte[] pluginBytes = File.ReadAllBytes(pluginName); byte[] symbolDatabaseBytes = File.ReadAllBytes(symbolDatabaseName); pluginAssembly = Assembly.Load(pluginBytes, symbolDatabaseBytes); } // load referenced assemblies...we don't need to do anything with it other than load it into the type universe List <AssemblyName> referecnedAssemblies = pluginAssembly.GetReferencedAssemblies().ToList(); foreach (AssemblyName referecnedAssembly in referecnedAssemblies) { Assembly.Load(referecnedAssembly); } // now that we have our assembly lets get types that are a plug-in type List <Type> frameworkElementPlugins = pluginAssembly.GetTypes().Where(type => typeof(IFrameworkElementPlugin).IsAssignableFrom(type)).ToList(); pluginTypeCollection.AddMany(frameworkElementPlugins); } catch (Exception ex) { throw new PluginException( FormattableString.Invariant( $"An error occurred attempting to load the plug-in assembly types for plug-in {location.AssemblyLocation}."), ex); } } return(pluginTypeCollection); }
/// <summary>Loads the plug-ins.</summary> /// <returns>A collection of the PluginModel's describing each plug-in.</returns> /// <exception cref="PluginException">An error occurred attempting to retrieve the plug-in assembly names.</exception> /// <exception cref="PluginException">An error occurred attempting to load the plug-in assembly types.</exception> /// <exception cref="PluginException">An error occurred attempting to build a plug-in model for type [type].</exception> public PluginModelCollection LoadPlugins() { IReadOnlyList <PluginLocation> plugins = PluginReader.ReadPluginDirectory(); PluginTypeCollection pluginTypeCollection = PluginReader.LoadPluginAssemblyTypes(plugins); PluginModelCollection pluginModelCollection = new PluginModelCollection(); if (pluginTypeCollection == null || pluginTypeCollection.Count == 0) { return(pluginModelCollection); } foreach (Type type in pluginTypeCollection) { try { PluginInstanceAllowanceAttribute pluginInstanceAllowanceAttribute = type.GetCustomAttribute <PluginInstanceAllowanceAttribute>(); PluginNameAttribute pluginNameAttribute = type.GetCustomAttribute <PluginNameAttribute>(); ControlWrapperAttribute pluginControlWrapperAttribute = type.GetCustomAttribute <ControlWrapperAttribute>(); ControlWrapper pluginControlWrapper = pluginControlWrapperAttribute?.ControlWrapper ?? ControlWrapper.LayoutAnchorable; InstanceAllowance pluginInstanceAllowance = pluginInstanceAllowanceAttribute?.InstanceAllowance ?? InstanceAllowance.Single; string pluginName = pluginNameAttribute?.PluginName ?? type.Name; // double check to make sure the PluginName wasn't set to "" or string.Empty if (string.IsNullOrWhiteSpace(pluginName)) { pluginName = type.Name; } pluginModelCollection.Add(new PluginModel(type, pluginInstanceAllowance, pluginName, pluginControlWrapper)); } catch (Exception ex) { throw new PluginException(FormattableString.Invariant($"An error occurred attempting to build a plug-in model for type {type}."), ex); } } return(pluginModelCollection); }
//如果返回 true 则表示该次调用有菜单项被输出 private bool GetDeviceMenu(PluginTypeCollection pluginTypes, ToolStripItemCollection menuItems) { bool bolIsOutput = false; for (int intIndex = 0; intIndex < pluginTypes.Count; intIndex++) { DevicePluginType _PluginType = pluginTypes[intIndex] as DevicePluginType; if ((_PluginType.Type.GetInterface(typeof(IDeviceHtmlPlugin).FullName, true) != null) || (Function.IsInheritableBaseType(_PluginType.Type, typeof(System.Windows.Forms.Control)))) { //HTML、控件 ToolStripMenuItem mnuDevicePlugin = new ToolStripMenuItem(); mnuDevicePlugin.Text = _PluginType.Name; mnuDevicePlugin.Image = _PluginType.Icon16; mnuDevicePlugin.Tag = _PluginType; if (_PluginType.Description != null && _PluginType.Description.Length > 0) { mnuDevicePlugin.ToolTipText = _PluginType.Description; } if (_PluginType.Icon16 != null) { mnuDevicePlugin.Image = _PluginType.Icon16; } mnuDevicePlugin.Click += new EventHandler(mnuDevicePlugin_Click); if (_PluginType.Children.Count > 0) { this.GetDeviceMenu(_PluginType.Children, mnuDevicePlugin.DropDownItems); } //mnuDevicePlugin.MouseEnter += new EventHandler(mnuDevicePlugin_MouseEnter); menuItems.Add(mnuDevicePlugin); bolIsOutput = true; } else if (Function.IsInheritableBaseType(_PluginType.Type, typeof(System.Windows.Forms.ToolStripItem))) { //自定义的菜单项 System.Reflection.ConstructorInfo ci = _PluginType.Type.GetConstructor(new System.Type[] { }); object objInstance = ci.Invoke(new object[] { }); IDevicePlugin plugin = objInstance as IDevicePlugin; ToolStripItem mnuDevicePlugin = plugin as ToolStripItem; if (_PluginType.Icon16 != null) { mnuDevicePlugin.Image = _PluginType.Icon16; } menuItems.Add(mnuDevicePlugin); plugin.SetDevices((Device[])mnuDevicePlugin.Owner.Tag); if (plugin is IUseAccount) { IUseAccount useAccount = plugin as IUseAccount; useAccount.SetAccount(this.CurrentAccount); } plugin.SetApplication(this); if (mnuDevicePlugin.Text.Length == 0) { mnuDevicePlugin.Text = _PluginType.Name; } if (_PluginType.Description != null && _PluginType.Description.Length > 0 && (mnuDevicePlugin.ToolTipText == null || mnuDevicePlugin.ToolTipText.Length == 0)) { mnuDevicePlugin.ToolTipText = _PluginType.Description; } //tsi.MouseEnter += new EventHandler(mnuDevicePlugin_MouseEnter); bolIsOutput = true; } else if (_PluginType.Name == null) { //分隔线 if (bolIsOutput && _PluginType.Children.Count > 0) { menuItems.Add(new ToolStripSeparator()); } //分隔线的子插件 if (this.GetDeviceMenu(_PluginType.Children, menuItems)) { bolIsOutput = true; } } else { //作为分类处理 if (_PluginType.Children.Count > 0) { ToolStripMenuItem mnuDevicePlugin = new ToolStripMenuItem(); mnuDevicePlugin.Text = _PluginType.Name; if (_PluginType.Description != null && _PluginType.Description.Length > 0) { mnuDevicePlugin.ToolTipText = _PluginType.Description; } if (_PluginType.Icon16 != null) { mnuDevicePlugin.Image = _PluginType.Icon16; } //mnuDevicePlugin.MouseEnter += new EventHandler(mnuDevicePlugin_MouseEnter); this.GetDeviceMenu(_PluginType.Children, mnuDevicePlugin.DropDownItems); menuItems.Add(mnuDevicePlugin); bolIsOutput = true; } } } return(bolIsOutput); }