WPF 手撸插件 三 插件文件热加载

news2024/9/27 12:15:41

1、在程序运行的同时将插件文件复制到指定的插件目录下,插件自动被加载。不废话了直接上代码吧。需要的可以帮我贡献点积分,谢谢各位大佬了。

示例文件下载icon-default.png?t=N7T8https://download.csdn.net/download/xingchengaiwei/896388912、主要功能代码如下。注意初学者建议 查看示例文件下载。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using AbstractionLayer;
using Path = System.IO.Path;

namespace WPFIPluginDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            //开始监控指定文件
            StartMonitoring(GetCurrentProgramPath() + "\\Plugins");
            //加载已存在的插件
            LoadPlugins(GetCurrentProgramPath() + "\\Plugins");
        }
        /// <summary>
        /// 文件监视
        /// </summary>
        private FileSystemWatcher _fileWatcher;
        /// <summary>
        /// 开始监视文件夹
        /// </summary>
        /// <param name="directoryPath"></param>
        private void StartMonitoring(string directoryPath)
        {
            // 创建 FileSystemWatcher 实例
            _fileWatcher = new FileSystemWatcher();

            // 设置要监视的目录路径
            _fileWatcher.Path = directoryPath;

            // 设置要监视的更改类型(例如:修改、创建、删除)
            _fileWatcher.NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;

            // 添加事件处理程序
            _fileWatcher.Changed += OnChanged;
            _fileWatcher.Created += OnChanged;
            _fileWatcher.Deleted += OnChanged;

            // 开启事件监听
            _fileWatcher.EnableRaisingEvents = true;

            Debug.WriteLine($"已开始监视文件夹: {directoryPath}");
        }
        /// <summary>
        /// 当文件夹中内容发生改变时触发时间
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void OnChanged(object source, FileSystemEventArgs e)
        {
            //Debug.WriteLine($"文件或文件夹发生变更: {e.FullPath},事件类型: {e.ChangeType}");
            if ((e.ChangeType & WatcherChangeTypes.Created) != 0)
            {
                if (File.Exists(e.FullPath))
                {
                    Debug.WriteLine("创建了文件");
                    LoadPlugins(GetCurrentProgramPath() + "\\Plugins");
                    Debug.WriteLine($"文件或文件夹发生变更: {e.FullPath},事件类型: {e.ChangeType}");

                }
                else
                {
                    Debug.WriteLine("创建了文件夹");
                }
            }
        }

        private bool IsDirectory(string path)
        {
            try
            {
                FileAttributes attr = File.GetAttributes(path);

                if ((attr & FileAttributes.Directory) ==FileAttributes.Directory)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception e)
            {
                return false;
            }
        }
        /// <summary>
        /// 停止监视文件夹
        /// </summary>
        public void StopMonitoring()
        {
            if (_fileWatcher != null)
            {
                // 停止引发事件
                _fileWatcher.EnableRaisingEvents = false;

                // 清理资源
                _fileWatcher.Dispose();
                _fileWatcher = null;

                Debug.WriteLine("已停止监视文件夹");
            }
        }
        /// <summary>
        /// 点击加载插件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnSearchPlugins_OnClick(object sender, RoutedEventArgs e)
        {
            LoadPlugins(GetCurrentProgramPath()+"\\Plugins");
        }
        /// <summary>
        /// 获取当前程序集的路径
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentProgramPath()
        {
            // 获取当前执行的程序集
            var assembly = Assembly.GetEntryAssembly();

            // 获取程序集所在的路径
            var assemblyLocation = assembly.Location;

            // 获取程序集所在的目录
            var programPath = Path.GetDirectoryName(assemblyLocation);

            return programPath;
        }
        /// <summary>
        /// 插件列表
        /// </summary>
        public List<IPlugin> ListIPlugins = new List<IPlugin>();
        /// <summary>
        /// 加载指定插件
        /// </summary>
        /// <param name="pluginDirectory"></param>
        public void LoadPlugins(string pluginDirectory)
        {
            try
            {
                Dispatcher.BeginInvoke(new Action(delegate
                {
                    // 获取所有插件DLL
                    var pluginDlls = Directory.GetFiles(pluginDirectory, "*.exe", SearchOption.TopDirectoryOnly);

                    foreach (var dll in pluginDlls)
                    {
                        try
                        {

                            Assembly pluginAssembly = Assembly.LoadFrom(dll);

                            // 查找实现了IPlugin接口的类型
                            var pluginTypes = pluginAssembly.GetTypes().Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsInterface);

                            foreach (var pluginType in pluginTypes)
                            {
                                IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType);
                                plugin.Initialize();
                                // 管理插件的代码
                                ListIPlugins.Add(plugin);
                            }
                        }
                        catch (Exception e)
                        {
                            Debug.WriteLine(e);

                            //throw;
                        }
                    }

                }));

            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
                //throw;
            }

        }
        /// <summary>
        /// 调用插件中的方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BtnShowPlugin_OnClick(object sender, RoutedEventArgs e)
        {
            Type plugin = ListIPlugins[0].GetType();

            MethodInfo showInfo = plugin.GetMethod("Show");//得到dll文件的中的方法

            showInfo.Invoke(ListIPlugins[0], null);//方法调用
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2052867.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云搜索专家实操:如何高效构建企业级 AI 搜索?

作者&#xff1a;来自阿里云搜索产品专家牛俊 本文由阿里云搜索产品专家牛俊在【AI 搜索 TechDay】上的分享【阿里云 AI 搜索 Demo 展示和动手实践】整理而成。 阿里云 AI 搜索的产品能力与业务价值 阿里云 AI 搜索的方案&#xff0c;基于阿里云 Elasticsearch Inference API…

什么是国债期货?怎么玩?

国债期货&#xff0c;也就是利率期货&#xff0c;是一种在交易所里买卖未来国债价格的金融工具。它允许投资者在今天定下价格&#xff0c;然后在将来的某个时间点进行交易。在中国&#xff0c;国债期货在金融期货交易所上市&#xff0c;有几种不同的期限&#xff0c;比如30年期…

CDGA|数据治理核心能力框架与数据治理体系规划

随着数字化转型的加速和大数据技术的广泛应用&#xff0c;数据已成为企业核心资产之一。如何高效、安全地管理和利用数据&#xff0c;成为企业提升竞争力和创新能力的重要课题。本文将从数据治理核心能力框架和数据治理体系规划两个方面进行探讨&#xff0c;以期为企业的数据治…

Controller中接收数组参数 post请求中在body中传+post请求中通过表单形式传(x-www-form-urlencoded)

1、场景 需要根据用户id集合批量删除用户数据&#xff0c;前端使用post请求&#xff0c;controller中参数接收数组参数并根据用户id删除用户基本信息 2、分析处理&#xff1a; 2.1、前端请求类型contentType:application/json 请求体中为json字符串&#xff0c;后端新建一个Us…

【GH】【EXCEL】bumblebee简介:GH↔EXCEL

文章目录 bumblebeeaddressComponentAnalysisAppCellChartingDataGraphicsRangeShapesWorkbooksWorksheets Sample: Accessing_ExcelExcel ApplicationWorkbookSave Workbook (Create)Get All Workbooks from AppGet Workbook by Name Get WorkbookGet Active Workbook from Ap…

python 阴暗图像 亮度增强 对比度增强 去雾

背景说明 最近在处理图像&#xff0c;发现一些样本由于逆光原因过于阴暗&#xff0c;影响图像识别。解决时&#xff0c;可以在训练样本中加入类似的图像&#xff0c;或者手动把相关图像进行颜色变化。这里主要介绍手工颜色变化。 原始图像如下&#xff0c;假设你需要判断裤子…

使用 Elasticsearch-DSL Python 客户端简化向量嵌入

作者&#xff1a;来自 Elastic Miguel Grinberg 在本文中&#xff0c;我们将介绍 Python 版 Elasticsearch-DSL 客户端&#xff0c;重点介绍它如何简化构建向量搜索解决方案的任务。 本文附带的代码实现了一个名言数据库。它包括一个使用 FastAPI Web 框架用 Python 编写的后端…

利用http获取文件升级

1.搭建模拟环境 1.电脑端开启Telnet客户端 2.下载HFS文件服务器 Download HFS_2024电脑最新版_HFS官方免费下载_华军软件园 (onlinedown.net) 将要升级的文件放到HFS文件系统中&#xff0c;这里我用了一个test.txt来作为实验 2.通过telnet敲http报文获取HFS服务器中的文件…

拼车系统功能案例分析

拼车系统功能案例分析可以从多个维度进行&#xff0c;以下是一个综合性的分析 一、用户注册与登录 功能描述&#xff1a;用户可以通过手机号、微信、QQ等多种方式轻松注册登录&#xff0c;并支持实名认证以增强身份真实性。案例分析&#xff1a;以T5出行拼车平台为例&#xff…

珂艾泰克拧紧控制器维修方法多样化

珂艾泰克拧紧控制器作为精密工业设备的关键组件&#xff0c;其稳定运行对于保证生产效率和产品质量至关重要。然而&#xff0c;在实际应用中&#xff0c;可能会因各种原因出现CORETEC拧紧控制器故障&#xff0c;影响生产线的正常运行。 【常见CORETEC拧紧控制器故障及原因分析】…

借助帕累托图减少设备停机时间:将非生产时间最小化

虽然全球通胀趋于稳定&#xff0c;但各行业仍能感受到2022年和2023年价格快速上涨的残余影响。对于石油和天然气公司来说&#xff0c;运营成本(包括设备、材料和劳动力)的上升加剧了财务压力。在这个竞争激烈的市场中&#xff0c;减少非生产时间(NPT)对于保持盈利能力至关重要。…

分享五种mfc140.dll丢失如何修复?五种修复错误的详细解决办法

在Windows操作系统中&#xff0c;DLL&#xff08;动态链接库&#xff09;文件扮演着至关重要的角色&#xff0c;它们为应用程序提供了共享的函数和资源。其中&#xff0c;mfc140.dll是Microsoft Visual C 2015 Redistributable Package的一部分&#xff0c;对于许多使用Microso…

会话管理

目录 一、为什么使用会话 二、cookie 1.概述 2.使用 &#xff08;1&#xff09; servletA向响应中增加Cookie &#xff08;2&#xff09;浏览器访问ServletA响应回来的响应报文携带cookie &#xff08;3&#xff09;浏览器访问ServletB&#xff0c;将携带cookie的请求报…

探索ORM宇宙:MyBatis-Plus的力量

**技术派项目源码地址 : ** **Gitee : 技术派 - https://gitee.com/itwanger/paicoding**Github : 技术派 - https://github.com/itwanger/paicoding **Mybatis-Plus 官网 : **MyBatis-Plus &#x1f680; 为简化开发而生 (baomidou.com) 整合Mybatis-Plus 引入依赖 <…

Flink之SQL client使用案例

Flink的执行模式有以下三种: 前提是我们已经开启了yarnsession的进程&#xff0c;在下图中可以看到启动的id也就是后续任务需要通过此id进行认证&#xff0c;以及任务分配的master主机。 这里启动时候会报错一个ERROR&#xff1a;org.apache.flink.shaded.curator.org.apache…

风电场风机安全监测系统解决方案

建设背景 随着风电产业的快速发展&#xff0c;风力发电已成为一种重要的清洁能源形式。风电场中的风塔是支撑风力发电机组的重要结构&#xff0c;其安全稳定运行对于风电场的正常运营和发电效率至关重要。然而&#xff0c;风塔常常面临风载、震动、腐蚀等多种外部因素的影响&a…

一键切换全球优质Linux 系统软件源及 Docker 源,轻松安装 Docker —— 适配广泛、零门槛、超强功能的开源脚本!

概述 linuxMirrors开源脚本为 GNU/Linux 系统用户提供了强大的工具,帮助用户轻松更换系统软件源并安装 Docker。脚本适配了多种国内外镜像站,经过测试具备良好的下载速度和 IPv6 兼容性,并且还包括了中国大陆教育网镜像站的选项。无需技术背景,文档提供了详尽的操作指引和常…

telegraf、influxdb、grafana安装配置及后端监听器操作

InfluxDB&#xff08;时序数据库&#xff09;&#xff0c;常用的一种使用场景&#xff1a;监控数据统计。 grafana&#xff0c;用作监控页面的前端展示。 telegraf&#xff0c;数据采集器。 ITG及快捷启动百度网盘&#xff1a;百度网盘 链接: 提取码: 0000 其他地址链接&am…

pycharm2023.1破解

下载解压文件&#xff0c;文件夹 /jetbra 复制电脑某个位置 注意&#xff1a; 补丁所属文件夹需单独存放&#xff0c;且放置的路径不要有中文与空格&#xff0c;以免 Pycharm 读取补丁错误。 点击进入 /jetbra 补丁目录&#xff0c;再点击进入 /scripts 文件夹&#xff0c;双…

JAVA中的网络编程巨详解(2w字)

在学习 Java 网络编程之前&#xff0c;我们先来了解什么是计算机网络。 计算机网络是指两台或更多的计算机组成的网络&#xff0c;在同一个网络中&#xff0c;任意两台计算机都可以直接通信&#xff0c;因为所有计算机都需要遵循同一种网络协议。 下面是一张简化的网络拓扑图…