如何清除加载的程序集,以便在重新加载插件时它不会重复

本文关键字:加载 插件 新加载 清除 何清除 程序集 | 更新日期: 2023-09-27 17:55:32

我这样做是为了让你可以打开一个dll并将其作为可点击的项目加载到列表框中,一旦点击,插件就会加载,你可以执行该插件。

我添加了一个清除按钮,该按钮应该清除当前加载的插件的应用程序。

它会

清除应用程序中的所有内容,但是当我再次加载它们时,它会加载重复项。

如何清除程序集,以便在重新加载插件时它不会重复?

代码隐藏:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using PluginContracts;
using System;
using System.IO;
using Microsoft.Win32;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;
using System.Diagnostics;
using System.Linq;
namespace SimplePlugin
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        Dictionary<string, IPlugin> _Plugins; // move to class scope

        public MainWindow()
        {
            InitializeComponent();
            _Plugins = new Dictionary<string, IPlugin>();
        }
        private void AssembleComponents(object sender)
        {

            string selection = "";
            if (sender is ListBox)
            {
                if (((ListBox)sender).SelectedValue != null)
                    selection = ((ListBox)sender).SelectedValue.ToString();
            }
            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            DirectoryCatalog cat = new DirectoryCatalog(path);
            //ICollection<IPlugin> plugins = PluginLoader.LoadPlugins("Plugins");
            ICollection<IPlugin> plugins = GenericPluginLoader<IPlugin>.LoadPlugins("Plugins");

            foreach (var item in plugins)
            {
                //add only if not already present
                if (!_Plugins.ContainsKey(item.Name))
                {
                    string dllName = GetDLLName(item.Name);
                    Button b = new Button() 
                    { 
                        Name = dllName.Replace(".", "").ToUpper(), 
                        Content = item.Name,
                        Visibility = System.Windows.Visibility.Hidden 
                    };
                    b.Click += b_Click;
                    PluginGrid.Children.Add(b);
                    _Plugins.Add(item.Name, item);

                   // this.PluginGrid.Children.Clear();  
                   //by Vasey
                }
            }

            // make visible the selected plugin button
   foreach (var ctl in PluginGrid.Children)
   {
       if (ctl is Button)
       {
           Button button = (Button)ctl;
           if (button.Name.Equals(selection.Replace(".", "").ToUpper()))
           {
               button.Visibility = System.Windows.Visibility.Visible;
           }
           else
           {
                button.Visibility = System.Windows.Visibility.Hidden;
           }
       }
   }
        }

        private void b_Click(object sender, RoutedEventArgs e)
        {
            Button b = sender as Button;
            if (b != null)
            {
                string key = b.Content.ToString();
                if (_Plugins.ContainsKey(key))
                {
                    IPlugin plugin = _Plugins[key];
                    plugin.Do();
                }
            }
        }
        private void addPlugin_Click(object sender, RoutedEventArgs e)
        {
            var fileDialog = new OpenFileDialog();
            fileDialog.Multiselect = true;
            fileDialog.Filter = "All files (*.*)|*.*|DLL files (*.dll)|*.dll|CS Files (*.cs)|*.cs";
            if (fileDialog.ShowDialog() == true)
            {
                string filename = fileDialog.FileName;
                var ext = System.IO.Path.GetExtension(filename);
                // ListBox lbFiles = new ListBox();
                //this.Controls.Add(lbFiles);
                //lbFiles.Size = new System.Drawing.Size(200, 100);
                //lbFiles.Location = new System.Drawing.Point(10, 10);
                lbFiles.Items.Add(System.IO.Path.GetFileName(filename));
                //  
                CopyToDir(filename);
            }
        }
        private void CopyToDir(string filename)
        {
            //  txtBox.Text = "Hello World";  
            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins");
            Console.WriteLine(path);
            //Check the directory exists
            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }
            try
            {
                FileInfo fi = new FileInfo(filename);
                if (!File.Exists(System.IO.Path.Combine(path, fi.Name)))
                {
                    File.Copy(fi.FullName, System.IO.Path.Combine(path, fi.Name));
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        // Get linkage between ListBox's DLL name list and the loaded plugin names
        string GetDLLName(string name)
        {
            string ret = "";
            name = name.Replace(" ", ""); // strip spaces
            Assembly asm = AppDomain.CurrentDomain.GetAssemblies().
                   SingleOrDefault(assembly => assembly.GetName().Name == name);
            if (asm != null)
            {
                ret = Path.GetFileName(asm.Location);
            }
            return ret;
        }

        private void lbFiles_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            AssembleComponents(sender);
        }
        private void ClearBtn_Click(object sender, RoutedEventArgs e)
        {
            lbFiles.Items.Clear();    
            _Plugins = new Dictionary<string, IPlugin>();
        }
    }
}

如何清除加载的程序集,以便在重新加载插件时它不会重复

我只需要将此函数添加到clearBtn方法中

//Clears the Assembly
        this.PluginGrid.Children.Clear();

以前

private void ClearBtn_Click(object sender, RoutedEventArgs e)
            {
                lbFiles.Items.Clear();    
                _Plugins = new Dictionary<string, IPlugin>();
            }

 private void ClearBtn_Click(object sender, RoutedEventArgs e)
    {
       // Clears the ListBox
        lbFiles.Items.Clear();
        //Clears the Assembly
        this.PluginGrid.Children.Clear();
        //Loads next Assembly 
        _Plugins = new Dictionary<string, IPlugin>();
    }