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

相关推荐
donk131416 小时前
React Native for OpenHarmony 实战:三方库 react-native-circular-action-menu 的鸿蒙化适配指南
javascript·分布式·react native·react.js·wpf·harmonyos
donk13141 天前
React Native for OpenHarmony 实战:三方库 react-native-step-indicator 的鸿蒙化适配指南
分布式·react native·react.js·wpf·harmonyos
He BianGu2 天前
【笔记】WPF中RenderOptions类的详细功能
笔记·wpf
VidDown2 天前
上线三个月后的第一次事故:一个 Django 服务的日志、监控与故障复盘
数据库·python·django·wpf·音视频·视频编解码
He BianGu2 天前
【笔记】WPF中CachingHint的功能
笔记·wpf
He BianGu2 天前
【笔记】在WPF中BitmapScalingMode的作用
笔记·wpf
Vae_Mars2 天前
幂等性学习笔记
笔记·学习·wpf
samble3 天前
从零搭建灌装监控系统(十九):单元测试实战,xUnit + 内存SQLite + 反射测试私有方法
c#·wpf·mvvm·modbus·工业控制
光泽雨4 天前
路由概念和路由事件 继承链路 RadioButton的事件解析
wpf
samble4 天前
从零搭建灌装监控系统(十八):自定义控件,三色灯与状态指示
c#·wpf·mvvm·modbus·工业控制