WPF 手撸插件 一

news2024/9/22 13:23:07

1、本文主要使不适用第三方工具,纯手工的WPF主项目加载另一个WPF的项目,这里我们加载的是*.exe。

2、项目结构如下图。AbstractionLayer用于创建插件的接口。WPFIPluginDemo是主程序。WpfPlugin3是要加载的插件程序。

3、 AbstractionLayer中添加接口IPlugin。接口内容如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AbstractionLayer
{
    public interface IPlugin
    {
        void Initialize();
    }
}

4、WPFIPluginDemo项目中MainWindow.xaml代码如下。

<Window x:Class="WPFIPluginDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPFIPluginDemo"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    
        
    <StackPanel>
        <Button x:Name="btnSearchPlugins" Content="搜索插件" Click="BtnSearchPlugins_OnClick"/>
        <Button x:Name="btnShowPlugin" Content="显示插件" Click="BtnShowPlugin_OnClick" Margin="0,10,0,0"/>
    </StackPanel>
</Window>

MainWindow.xaml.cs代码如下。

using System;
using System.Collections.Generic;
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();
        }

        private void BtnSearchPlugins_OnClick(object sender, RoutedEventArgs e)
        {
            LoadPlugins(GetCurrentProgramPath()+"\\Plugins");
        }

        public static string GetCurrentProgramPath()
        {
            // 获取当前执行的程序集
            var assembly = Assembly.GetEntryAssembly();

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

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

            return programPath;
        }

        public List<IPlugin> ListIPlugins = new List<IPlugin>();
        public void LoadPlugins(string pluginDirectory)
        {
            try
            {
                // 获取所有插件DLL
                var pluginDlls = Directory.GetFiles(pluginDirectory, "*.exe", SearchOption.TopDirectoryOnly);

                foreach (var dll in pluginDlls)
                {
                    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)
            {
                Console.WriteLine(e);
                throw;
            }

        }

        private void BtnShowPlugin_OnClick(object sender, RoutedEventArgs e)
        {
            Type plugin = ListIPlugins[0].GetType();

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

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

5、WpfPlugin3项目中创建WpfPlugin.cs。代码如下。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using AbstractionLayer;

namespace WpfPlugin3
{
    public class WpfPlugin : IPlugin
    {
        public MainWindow _MainWindow = null;
        public void Initialize()
        {
            _MainWindow = new MainWindow();
        }

        public void Show()
        {
            if (_MainWindow!=null)
            {
                _MainWindow.ShowDialog();
            }
        }
    }
}

MainWindow.xaml代码如下。

<Window x:Class="WpfPlugin3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfPlugin3"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" WindowStyle="None">
    <Grid>
        <Button Content="WpfPlugin3" Width="200" Height="200"></Button>
    </Grid>
</Window>

6、在WPFIPluginDemo的Debug目录下创建文件夹Plugins,将WpfPlugin3.exe复制到此文件夹下。如下图。

7、示例代码下载路径。

https://download.csdn.net/download/xingchengaiwei/89535331

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

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

相关文章

昇思25天学习打卡营第22天 | 基于MobileNetv2的垃圾分类函数式自动微分

基于MobileNetV2的垃圾分类 本文档详细介绍了使用MobileNetV2模型进行垃圾分类的全过程&#xff0c;包括数据准备、模型搭建、模型训练、评估和推理等步骤。MobileNetV2是一种轻量级卷积神经网络&#xff0c;专为移动端和嵌入式设备设计&#xff0c;具有高效、低耗的特点。通过…

昇思25天学习打卡营第21天|RNN实现情感分类

这节课学习的是RNN实现情感分类&#xff0c;情感分类是自然语言处理中的经典任务&#xff0c;是典型的分类问题。本节使用MindSpore实现一个基于RNN网络的情感分类模型。 比如&#xff1a; 输入: This film is terrible 正确标签: Negative 预测标签: Negative 输入: This film…

Matlab进阶绘图第63期—带标记线的三维填充折线图

三维填充折线图是在三维折线图的基础上&#xff0c;对其与XOY平面之间的部分进行颜色填充&#xff0c;从而能够更好地刻画细节变化。 而带标记线的三维填充折线图是在其基础上&#xff0c;添加X相同的一条或多条标记线&#xff0c;以用于进一步讨论分析。 由于Matlab中未收录…

Mongodb复合索引

学习mongodb&#xff0c;体会mongodb的每一个使用细节&#xff0c;欢迎阅读威赞的文章。这是威赞发布的第90篇mongodb技术文章&#xff0c;欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题&#xff0c;欢迎在文章下面点个赞&#xff0c;或者关…

Windows上LabVIEW编译生成可执行程序

LabVIEW项目浏览器(Project Explorer)中的"Build Specifications"就是用来配置项目发布方法的。在"Build Specifications"右键菜单中选取"New"&#xff0c;可以看到程序有几种不同的发布方法&#xff1a;Application(EXE)、Installer、.Net Inte…

C# 基于共享内存实现跨进程队列

C# 进程通信系列 第一章 共享内存 第二章 共享队列&#xff08;本章&#xff09; 文章目录 C# 进程通信系列前言一、实现原理1、用到的主要对象2、创建共享内存3、头部信息4、入队5、出队6、释放资源 二、完整代码三、使用示例1、传输byte[]数据2、传输字符串3、传输对象 总结…

HarmonyOS 屏幕适配设计

1. armonyOS 屏幕适配设计 1.1. 像素单位 &#xff08;1&#xff09;px (Pixels)   px代表屏幕上的像素点&#xff0c;是手机屏幕分辨率的单位&#xff0c;即屏幕物理像素单位。 &#xff08;2&#xff09;vp (Viewport Percentage)   vp是视口百分比单位&#xff0c;基于…

Java学习之SPI、JDBC、SpringFactoriesLoader、Dubbo

概述 SPI&#xff0c;Service Provider Interface&#xff0c;一种服务发现机制&#xff0c;指一些提供给你继承、扩展&#xff0c;完成自定义功能的类、接口或方法。 在SPI机制中&#xff0c;服务提供者为某个接口实现具体的类&#xff0c;而在运行时通过SPI机制&#xff0c…

Facebook未来展望:数字社交平台的进化之路

在信息技术日新月异的时代&#xff0c;社交媒体平台不仅是人们交流沟通的重要工具&#xff0c;更是推动社会进步和变革的重要力量。作为全球最大的社交媒体平台之一&#xff0c;Facebook在过去十多年里&#xff0c;不断创新和发展&#xff0c;改变了数十亿用户的社交方式。展望…

构建企业多层社会传播网络:以AI智能名片S2B2C商城小程序为例

摘要&#xff1a;在数字化转型的浪潮中&#xff0c;企业如何有效构建并优化其社会传播网络&#xff0c;已成为提升市场竞争力、深化用户关系及实现价值转化的关键。本文以AI智能名片S2B2C商城小程序为例&#xff0c;深入探讨如何通过一系列精细化的策略与技术创新&#xff0c;构…

IP地址知识点

一、IP地址组成 把一个IP地址分成两部分&#xff1a;网络号&#xff08;标识了一个局域网&#xff09;主机号&#xff08;标识了一个局域网中的设备&#xff09; 下图是通过一个路由器连接的两个局域网&#xff08;两个相邻的局域网&#xff09;&#xff0c;网络号不相同&…

AI绘画入门实践|Midjourney 的模型版本

模型分类 Midjourney 的模型主要分为2大类&#xff1a; 默认模型&#xff1a;目前包括&#xff1a;V1, V2, V3, V4, V5.0, V5.1, V5.2, V6 NIJI模型&#xff1a;目前包括&#xff1a;NIJI V4, NIJI V5, NIJI V6 模型切换 你在服务器输入框中输入 /settings&#xff1a; 回车后…

Mac电脑清理软件有哪些 MacBooster和CleanMyMac哪个好用 苹果电脑清理垃圾软件推荐 cleanmymac和柠檬清理

对于苹果电脑用户来说&#xff0c;‌选择合适的清理软件可以帮助优化电脑性能&#xff0c;‌释放存储空间&#xff0c;‌并确保系统安全。一款好用的苹果电脑清理软件&#xff0c;能让Mac系统保持良好的运行状态&#xff0c;避免系统和应用程序卡顿的产生。有关Mac电脑清理软件…

什么是MOW,以bitget钱包为例

元描述&#xff1a;MOW凭借其富有创意的故事情节和广阔的潜力在Solana上脱颖而出。本文深入探讨了其独特的概念和光明的未来。 Mouse in a Cats World (MOW)是一个基于Solana区块链的创新meme项目&#xff0c;它重新构想了一个异想天开且赋予权力的故事。在这个奇幻的宇宙中&am…

JuiceFS、Ceph 和 MinIO 结合使用

1. 流程图 将 JuiceFS、Ceph 和 MinIO 结合使用&#xff0c;可以充分利用 Ceph 的分布式存储能力、JuiceFS 的高性能文件系统特性&#xff0c;以及 MinIO 提供的对象存储接口。以下是一个方案&#xff0c;介绍如何配置和部署 JuiceFS 使用 Ceph 作为其底层存储&#xff0c;并通…

非法闯入智能监测摄像机:安全守护的新利器

在当今社会&#xff0c;安全问题愈发受到重视。随着科技的进步&#xff0c;非法闯入智能监测摄像机应运而生&#xff0c;成为保护家庭和财产安全的重要工具。这种摄像机不仅具备监控功能&#xff0c;还集成了智能识别和报警系统&#xff0c;能够在第一时间内检测到潜在的入侵行…

three.js创建基础模型

场景是一个三维空间&#xff0c;是所有物品的容器。可以将其想象成一个空房间&#xff0c;里面可以放置要呈现的物体、相机、光源等。 通过new THREE.Scene()来创建一个新的场景。 /**1. 创建场景 -- 放置物体对象的环境*/ const scene new THREE.Scene();场景只是一个三维的…

JVM(day2)

经典垃圾收集器 Serial收集 使用一个处理器或一条收集线程去完成垃圾收集工作&#xff0c;更重要的是强调在它进行垃圾收集时&#xff0c;必须暂停其他所有工作线程&#xff0c;直到它收集结束。 ParNew收集器 ParNew 收集器除了支持多线程并行收集之外&#xff0c;其他与 …

HTTP背后的故事:理解现代网络如何工作的关键(二)

一.认识请求方法(method) 1.GET方法 请求体中的首行包括&#xff1a;方法&#xff0c;URL&#xff0c;版本号 方法描述的是这次请求&#xff0c;是具体去做什么 GET方法&#xff1a; 1.GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源。 2.在浏览器中直接输入 UR…

【实战:Django-Celery-Flower实现异步和定时爬虫及其监控邮件告警】

1 Django中集成方式一&#xff08;通用方案&#xff09; 1.1 把上面的包-复制到djagno项目中 1.2 在views中编写视图函数 1.3 配置路由 1.4 浏览器访问&#xff0c;提交任务 1.5 启动worker执行任务 1.6 查看任务结果 2 Django中集成方式二&#xff08;官方方案&#xff0…