WPF 手撸插件 一

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

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

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

cs 复制代码
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代码如下。

XML 复制代码
<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代码如下。

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。代码如下。

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代码如下。

XML 复制代码
<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

相关推荐
云中飞鸿1 天前
WPF分哪几块
wpf
newbe365241 天前
我们如何使用 impeccable 优化前端界面设计与实现稳定性
前端·人工智能·分布式·github·aigc·wpf
Chris _data19 天前
WPF 学习第三天 — Modbus RTU 串口通信
hadoop·学习·wpf
布吉岛的石头20 天前
Java 程序员第 43 阶段05:微服务整合大模型,跨服务调用架构设计实战,Seata分布式事务实战
wpf
步步为营DotNet20 天前
基于.NET Aspire 实现云原生应用的高效监控与可观测性
云原生·.net·wpf
芒鸽20 天前
HarmonyOS 分布式开发实战:设备协同、数据共享与跨设备迁移
分布式·wpf·harmonyos
Volunteer Technology20 天前
Flink状态管理与容错(二)
大数据·flink·wpf
happyprince21 天前
07_verl-Trainer模块详解
人工智能·架构·wpf·强化学习
bugcome_com21 天前
WPF + Prism 技术指南与实战项目(二、模板搭建)
wpf
小满Autumn21 天前
log4net 日志框架 — 从配置到实战速查手册
笔记·c#·.net·wpf·上位机·log4net