首页 > 编程语言 >c# Winform热插拔

c# Winform热插拔

时间:2023-06-10 14:22:34浏览次数:25  
标签:string c# System private 热插拔 Path using public Winform

1.定义接口

 public interface IUltraman
    {
        string UltramanName { get; set; }
        string Name { get; set; }
        string Attack();

    }

2.接口的继承

编译为不同的dll文件

    public class Taro : IUltraman
    {
        private string name = "Taro";
        public string Name { get => name; set => name = value; }
        private string ultramanName = "泰罗atm";
        public string UltramanName { get => ultramanName; set => ultramanName = value; }


        public string Attack()
        {
            return "Taro attack monster";
        }
    }
    
    public class Ace : IUltraman
    {
        private string name = "Ace";
        public string Name { get => name; set => name = value; }
        private string ultramanName = "艾斯atm";
        public string UltramanName { get=> ultramanName; set=> ultramanName = value; }


        public string Attack()
        {
            return "Ace attack monster";
        }
    }
    

3.读取dll文件为字节流

public class FileToMemory
    {

        public static void ToMemory(string fullName,out byte[] fileBytes)
        {
            using (FileStream fs = new FileStream(fullName,FileMode.Open,FileAccess.Read))
            {
                fileBytes = new byte[fs.Length];
                fs.Read(fileBytes, 0, fileBytes.Length);
            }
        }

    }

4.winform中代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ultraman;

namespace SelectUltraman
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            //开始监视
            StartWatch();
            //加载dll生成button
            LoadButton();
        }


        private void StartWatch()
        {
            //获取program所在的目录
            string root = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location)));
            //获取全目录地址
            string fullPath = Path.GetFullPath(Path.Combine(root, "Plugs"));
            //文件夹监视
            var watcher = new FileSystemWatcher(fullPath);
            watcher.EnableRaisingEvents = true;//启动监听
            //采用委托的方式 
            //beginInvoke是线程执行后执行的
            //invoke是立刻执行的
            //当文件夹中新增文件
            watcher.Created += (s,e)=> { this.BeginInvoke(new FileChange(LoadButton)); };
            //当文件夹中删除文件
            watcher.Deleted += (s, e) => { this.BeginInvoke(new FileChange(LoadButton)); };
            //当文件夹中重命名文件
            watcher.Renamed += (s, e) => { this.BeginInvoke(new FileChange(LoadButton)); };
        }

        delegate void FileChange();

        private void LoadButton()
        {
            //情况panel中的控件
            flowLayoutPanel1.Controls.Clear(); 
            //加载插件地址
            List<string> plugPaths = LoadPlugPaths("Plugs");
            IEnumerable<IUltraman> ultramens = plugPaths.SelectMany(p =>
            {
                Assembly plugAssembly = LoadPlugs(p);
                return CreateUltraman(plugAssembly);
            });

            foreach (var ultraman in ultramens)
            {
                Button btn = new Button()
                {
                    Text = ultraman.UltramanName,
                    Tag = ultraman.Name
                };
                btn.Click += button_Click;
                flowLayoutPanel1.Controls.Add(btn);
            }
        }

        private IEnumerable<IUltraman> CreateUltraman(Assembly plugAssembly)
        {
            Type[] types = plugAssembly.GetExportedTypes();
            IEnumerable<Type> allTypes = types.Where(m => !m.IsAbstract);
            foreach (var type in allTypes)
            {
                IUltraman ultraman = Activator.CreateInstance(type) as IUltraman;
                yield return ultraman;
            }
        }

        private Assembly LoadPlugs(string p)
        {
            FileToMemory.ToMemory(p,out byte[] data);
            return Assembly.Load(data);
        }

        private List<string> LoadPlugPaths(string path)
        {
            string root = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(typeof(Program).Assembly.Location)));
            string fullPath = Path.GetFullPath(Path.Combine(root, path));
            string[] files = Directory.GetFiles(fullPath);
            return files.ToList();
        }

        private void button_Click(object sender, EventArgs e)
        {
            Button button = (Button)sender;
            string tag = button.Tag as string;
            string text = GetUltraman(tag);
            MessageBox.Show(text);
        }

        private string GetUltraman(string tag)
        {
            List<string> plugPaths = LoadPlugPaths("Plugs");
            IEnumerable<IUltraman> ultramens = plugPaths.SelectMany(p =>
            {
                Assembly plugAssembly = LoadPlugs(p);
                return CreateUltraman(plugAssembly);
            });

            var ultramen = ultramens.FirstOrDefault(m=>m.Name == tag);
            if (ultramen != null)
            {
                return ultramen.Attack();
            }
            else
            {
                return null;
            }
        }

    }
}

 

标签:string,c#,System,private,热插拔,Path,using,public,Winform
From: https://www.cnblogs.com/HRDK-CADeveloper/p/17471218.html

相关文章

  • 5.26日学习总结之网络编程socket
    Pythonsocket编程在网络上的教程较少,菜鸟中也只是给出了一小段描述,在此我推荐白羽黑夜socket编程|白月黑羽(byhy.net)其中的描写非常详细,本人也是在此学习的。socket又被称作套接字,可以简单的看作是两个地址(ip,port地址)之间通过socket的函数来进行传递数据。socket在客户端......
  • ubuntu安装miniconda及其可能出现的问题
    什么是minicondaMiniconda是一个轻量级的Conda发行版,它是Anaconda的一个精简版本。Anaconda是一个流行的Python发行版,内置了Python解释器以及大量科学计算和数据科学相关的软件包。Miniconda的目标是提供一个更精简和灵活的发行版,它只包含了Conda包管理器和Python解释器,没有预安......
  • Electron 案例
     Electron简介Electron是干什么的?简单来讲,Electron使用JavaScript,HTML和CSS,来构建跨平台的桌面应用程序。按照官方的说法:如果你可以建一个网站,你就可以建一个桌面应用程序。和传统的桌面应用相比,使用Electron开发更容易上手,开发效率更高。并且,web技术应用广泛、生态......
  • Docker安装Jenkins报错后升级Centos7升级内核
    很久没碰docker了,昨晚在虚拟机上用dockerpulljenkinsci/blueocean安装Jenkins启动报如下错误:java.net.UnknownHostException:updates.jenkins.io最后发现容器pingdocker0都是不通的,尴尬,想想应该是内核或docker版本的问题,安装的centos7内核版本是3.10,升级到最新稳定版5.x后重......
  • Python+OpenGL使用Cohen-Sutherland算法实现直线裁剪
    问题描述:编写Python程序,使用OpenGL实现用于直线裁剪的Cohen-Sutherland算法。运行程序,绘制一个矩形表示裁剪窗口,然后通过鼠标单击和移动来绘制直线,鼠标抬起时对刚刚绘制的直线进行裁剪,显示最终落在裁剪窗口中的部分。关于Cohen-Sutherland算法请自行查阅资料。准备工作:安装和配置Py......
  • Python+Pandas读取Excel文件分析关系最好的两个演员
    问题描述:已知Excel文件“电影导演演员.xlsx”中内容如下所示,后台发送消息“20220119”下载文件:编写程序,读取Excel文件中的数据,分析共同参演电影数量最多的两个演员,也就是关系最好的两个演员,要求尽可能多地使用Pandas来完成任务。参考代码:运行结果:['演员3''演员4']公众号“Python小......
  • Python+pywin32操作Excel文件常用功能(268行代码+注释)
    问题描述:使用Python扩展库pywin32操作Excel文件。准备工作:安装Python,安装扩展库pywin32,安装Office或WPS。参考代码:运行结果:公众号“Python小屋”......
  • 关于AWS-EC2-EBS-快照-或者AMI-创建的过程及原理
    对于AWSEC2的EBS创建快照Snapshot的原理逻辑,主要如下快照是异步制作的;时间点快照是立即创建的,但在快照完成(当所有已修改数据块都已转移到AmazonS3时)之前,其状态为 pending,很多大型初始快照或后续快照(其中的数据块已更改)可能需要几个小时才能完成。执行期间,正在进行的快照......
  • GoLand 2023(GO语言集成开发工具环境)mac版
    GoLand是一个非常简单的Go语言开发工具,它使您能够在各种平台上构建Go应用程序。在过去的几年里,GoLand2023在各个领域进行了改进,并且继续发展。我们从这篇文章开始,以了解GoLand的新功能。GoLand的一个很棒的功能是允许您设置源代码,而不仅仅是编译它。这使您可以在编写代码之前......
  • Rocky Linux 安装 Open Project
    一、概要1.环境(1)RockyLinux9.12.准备(1)SSL证书a.创建私钥目录sudomkdir/etc/ssl/privateb.生成证书和密钥OpenSSL系列c.移动证书sudomvopenproject.example.com.crt.pem/etc/ssl/certssudomvopenproject.example.com.key.pem/etc/ssl/private......