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

相关推荐
阿登林4 小时前
初步学习WPF-Prism
学习·wpf
△曉風殘月〆12 小时前
WPF MVVM进阶系列教程(三、使用依赖注入)
wpf·mvvm
此wei浩亦14 小时前
WPF中使用 using prism.region 报错
c#·wpf·prism
dotent·1 天前
一个 WPF 文档和工具窗口布局容器
wpf
c#上位机1 天前
wpf之ComboBox
wpf
lindexi2 天前
WPF 引用 ASP.NET Core 的 AOT 版本
wpf·asp.netcore
我好喜欢你~2 天前
WPF---数据模版
wpf
hqwest3 天前
C#WPF实战出真汁07--【系统设置】--菜品类型设置
开发语言·c#·wpf·grid设计·stackpanel布局
hqwest4 天前
C#WPF实战出真汁08--【消费开单】--餐桌面板展示
c#·wpf·ui设计·wpf界面设计
orangapple4 天前
WPF 打印报告图片大小的自适应(含完整示例与详解)
c#·wpf