From 7a30c93ff5a625f22e6b2b72ea09489b983eef0c Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 5 Apr 2026 14:12:35 +0800 Subject: [PATCH] =?UTF-8?q?delete:=E6=8F=92=E4=BB=B6=E7=B3=BB=E7=BB=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas.sln | 68 +- .../BuiltIn/SuperLauncher/LauncherButton.cs | 274 --- .../BuiltIn/SuperLauncher/LauncherModels.cs | 332 ---- .../LauncherSettingsControl.xaml | 143 -- .../LauncherSettingsControl.xaml.cs | 396 ---- .../BuiltIn/SuperLauncher/LauncherWindow.xaml | 91 - .../SuperLauncher/LauncherWindow.xaml.cs | 466 ----- .../Plugins/BuiltIn/SuperLauncherPlugin.cs | 589 ------ Ink Canvas/Helpers/Plugins/IActionService.cs | 296 --- .../Helpers/Plugins/ICCPPPluginAdapter.cs | 180 -- Ink Canvas/Helpers/Plugins/IGetService.cs | 214 --- Ink Canvas/Helpers/Plugins/IPlugin.cs | 67 - Ink Canvas/Helpers/Plugins/IPluginService.cs | 38 - Ink Canvas/Helpers/Plugins/IWindowService.cs | 152 -- Ink Canvas/Helpers/Plugins/PluginBase.cs | 166 -- Ink Canvas/Helpers/Plugins/PluginManager.cs | 1622 ----------------- Ink Canvas/Helpers/Plugins/PluginRuntime.cs | 25 - .../Helpers/Plugins/PluginSdkHostContext.cs | 1289 ------------- .../Helpers/Plugins/PluginServiceManager.cs | 24 - .../Helpers/Plugins/SdkPluginAdapter.cs | 133 -- Ink Canvas/InkCanvasForClass.csproj | 4 - Ink Canvas/MainWindow.xaml | 28 - Ink Canvas/MainWindow.xaml.cs | 73 - .../MainWindow_cs/MainWindow_PluginHostApi.cs | 152 -- Ink Canvas/Windows/PluginSettingsWindow.xaml | 179 -- .../Windows/PluginSettingsWindow.xaml.cs | 727 -------- .../SettingsViews/StartupPanel.xaml | 9 - Plugins/Host/CollectingPluginRegistry.cs | 104 -- Plugins/Host/InkCanvas.PluginHost.csproj | 16 - Plugins/SDK/IInkCanvasPlugin.cs | 103 -- Plugins/SDK/IPluginContext.cs | 569 ------ Plugins/SDK/IPluginRegistry.cs | 32 - Plugins/SDK/InkCanvas.PluginSdk.csproj | 35 - Plugins/SDK/InkCanvasPluginBase.cs | 268 --- Plugins/SDK/NotificationType.cs | 28 - Plugins/SDK/README.md | 160 -- .../SampleClockPlugin/ClockOverlayPlugin.cs | 137 -- .../SampleClockPlugin.csproj | 16 - 38 files changed, 1 insertion(+), 9204 deletions(-) delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml.cs delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs delete mode 100644 Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs delete mode 100644 Ink Canvas/Helpers/Plugins/IActionService.cs delete mode 100644 Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs delete mode 100644 Ink Canvas/Helpers/Plugins/IGetService.cs delete mode 100644 Ink Canvas/Helpers/Plugins/IPlugin.cs delete mode 100644 Ink Canvas/Helpers/Plugins/IPluginService.cs delete mode 100644 Ink Canvas/Helpers/Plugins/IWindowService.cs delete mode 100644 Ink Canvas/Helpers/Plugins/PluginBase.cs delete mode 100644 Ink Canvas/Helpers/Plugins/PluginManager.cs delete mode 100644 Ink Canvas/Helpers/Plugins/PluginRuntime.cs delete mode 100644 Ink Canvas/Helpers/Plugins/PluginSdkHostContext.cs delete mode 100644 Ink Canvas/Helpers/Plugins/PluginServiceManager.cs delete mode 100644 Ink Canvas/Helpers/Plugins/SdkPluginAdapter.cs delete mode 100644 Ink Canvas/MainWindow_cs/MainWindow_PluginHostApi.cs delete mode 100644 Ink Canvas/Windows/PluginSettingsWindow.xaml delete mode 100644 Ink Canvas/Windows/PluginSettingsWindow.xaml.cs delete mode 100644 Plugins/Host/CollectingPluginRegistry.cs delete mode 100644 Plugins/Host/InkCanvas.PluginHost.csproj delete mode 100644 Plugins/SDK/IInkCanvasPlugin.cs delete mode 100644 Plugins/SDK/IPluginContext.cs delete mode 100644 Plugins/SDK/IPluginRegistry.cs delete mode 100644 Plugins/SDK/InkCanvas.PluginSdk.csproj delete mode 100644 Plugins/SDK/InkCanvasPluginBase.cs delete mode 100644 Plugins/SDK/NotificationType.cs delete mode 100644 Plugins/SDK/README.md delete mode 100644 Plugins/Samples/SampleClockPlugin/ClockOverlayPlugin.cs delete mode 100644 Plugins/Samples/SampleClockPlugin/SampleClockPlugin.csproj diff --git a/Ink Canvas.sln b/Ink Canvas.sln index 29bb5abd..9e46f5cd 100644 --- a/Ink Canvas.sln +++ b/Ink Canvas.sln @@ -1,16 +1,10 @@ - + Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.5.33530.505 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InkCanvasForClass", "Ink Canvas\InkCanvasForClass.csproj", "{8D0EDFC7-F974-4571-BC49-6F3A6653FE81}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InkCanvas.PluginSdk", "Plugins\SDK\InkCanvas.PluginSdk.csproj", "{E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InkCanvas.PluginHost", "Plugins\Host\InkCanvas.PluginHost.csproj", "{E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleClockPlugin", "Plugins\Samples\SampleClockPlugin\SampleClockPlugin.csproj", "{60891C83-8F04-438E-8064-D827E7AC1817}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -45,66 +39,6 @@ Global {8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x64.Build.0 = Release|Any CPU {8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x86.ActiveCfg = Release|Any CPU {8D0EDFC7-F974-4571-BC49-6F3A6653FE81}.Release|x86.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|ARM.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|ARM.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|ARM64.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|x64.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|x64.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|x86.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Debug|x86.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|Any CPU.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|ARM.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|ARM.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|ARM64.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|ARM64.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|x64.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|x64.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|x86.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7081}.Release|x86.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|Any CPU.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|ARM.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|ARM.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|ARM64.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|x64.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|x64.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|x86.ActiveCfg = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Debug|x86.Build.0 = Debug|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|Any CPU.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|ARM.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|ARM.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|ARM64.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|ARM64.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|x64.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|x64.Build.0 = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|x86.ActiveCfg = Release|Any CPU - {E4B8F2A1-6C3D-4E9F-A1B2-3C4D5E6F7082}.Release|x86.Build.0 = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|Any CPU.Build.0 = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|ARM.ActiveCfg = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|ARM.Build.0 = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|ARM64.ActiveCfg = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|ARM64.Build.0 = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|x64.ActiveCfg = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|x64.Build.0 = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|x86.ActiveCfg = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Debug|x86.Build.0 = Debug|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|Any CPU.ActiveCfg = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|Any CPU.Build.0 = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|ARM.ActiveCfg = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|ARM.Build.0 = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|ARM64.ActiveCfg = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|ARM64.Build.0 = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|x64.ActiveCfg = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|x64.Build.0 = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|x86.ActiveCfg = Release|Any CPU - {60891C83-8F04-438E-8064-D827E7AC1817}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs deleted file mode 100644 index 479387db..00000000 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherButton.cs +++ /dev/null @@ -1,274 +0,0 @@ -using iNKORE.UI.WPF.Controls; -using System; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; - -namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher -{ - /// - /// 启动台按钮控件 - /// - public class LauncherButton - { - /// - /// 父插件 - /// - private readonly SuperLauncherPlugin _plugin; - - /// - /// 实际按钮控件 - /// - private readonly SimpleStackPanel _panel; - - /// - /// 获取按钮UI元素 - /// - public UIElement Element => _panel; - - /// - /// 构造函数 - /// - /// 父插件 - public LauncherButton(SuperLauncherPlugin plugin) - { - try - { - _plugin = plugin; - LogHelper.WriteLogToFile("开始创建启动台按钮"); - - // 创建SimpleStackPanel - _panel = new SimpleStackPanel - { - Name = "Launcher_Icon", - Orientation = Orientation.Vertical, - HorizontalAlignment = HorizontalAlignment.Center, - Width = 28, - Margin = new Thickness(0, -2, 0, 0), - Background = Brushes.Transparent - }; - - LogHelper.WriteLogToFile("创建SimpleStackPanel完成"); - - // 添加图标 - var image = CreateIconImage(); - _panel.Children.Add(image); - - // 添加文本 - TextBlock textBlock = new TextBlock - { - Text = "启动台", - Foreground = Brushes.Black, - FontSize = 8, - Margin = new Thickness(0, 1, 0, 0), - TextAlignment = TextAlignment.Center - }; - _panel.Children.Add(textBlock); - - // 设置鼠标事件 - _panel.MouseDown += Panel_MouseDown; - _panel.MouseUp += Panel_MouseUp; - _panel.MouseLeave += Panel_MouseLeave; - - // 右键菜单支持 - _panel.ContextMenu = CreateContextMenu(); - - // 设置工具提示 - _panel.ToolTip = "启动台"; - - LogHelper.WriteLogToFile("启动台按钮创建完成"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"创建启动台按钮时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - /// - /// 创建右键菜单 - /// - private ContextMenu CreateContextMenu() - { - try - { - // 创建菜单 - ContextMenu menu = new ContextMenu(); - - // 创建位置切换菜单项 - MenuItem positionMenuItem = new MenuItem(); - positionMenuItem.Header = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left ? - "移至右侧" : "移至左侧"; - positionMenuItem.Click += (s, e) => - { - // 切换位置 - _plugin.Config.ButtonPosition = _plugin.Config.ButtonPosition == LauncherButtonPosition.Left ? - LauncherButtonPosition.Right : LauncherButtonPosition.Left; - - // 更新按钮位置 - _plugin.UpdateButtonPosition(); - - // 保存配置 - _plugin.SaveConfig(); - - LogHelper.WriteLogToFile($"通过右键菜单切换启动台按钮位置为: {_plugin.Config.ButtonPosition}"); - }; - menu.Items.Add(positionMenuItem); - - // 添加设置菜单项 - MenuItem settingsMenuItem = new MenuItem(); - settingsMenuItem.Header = "打开设置"; - settingsMenuItem.Click += (s, e) => - { - // 打开插件设置窗口 - var mainWindow = Application.Current.MainWindow; - if (mainWindow != null) - { - try - { - // 使用反射调用主窗口的ShowPluginSettings方法 - var method = mainWindow.GetType().GetMethod("ShowPluginSettings"); - if (method != null) - { - method.Invoke(mainWindow, null); - LogHelper.WriteLogToFile("已打开插件设置窗口"); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"打开插件设置窗口失败: {ex.Message}", LogHelper.LogType.Error); - } - } - }; - menu.Items.Add(settingsMenuItem); - - return menu; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"创建右键菜单时出错: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 获取实际的UI元素 - /// - [Obsolete("使用Element属性代替")] - public UIElement GetUIElement() - { - return _panel; - } - - /// - /// 创建图标图像 - /// - private Image CreateIconImage() - { - try - { - // 创建图像 - Image image = new Image - { - Height = 17, - Margin = new Thickness(0, 3, 0, 0) - }; - - // 设置位图缩放模式 - RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.HighQuality); - - // 创建绘图图像 - DrawingImage drawingImage = new DrawingImage(); - DrawingGroup drawingGroup = new DrawingGroup(); - drawingGroup.ClipGeometry = Geometry.Parse("M0,0 V24 H24 V0 H0 Z"); - - // 使用提供的应用网格图标 - GeometryDrawing geometryDrawing = new GeometryDrawing - { - Brush = new SolidColorBrush(Color.FromRgb(0x1B, 0x1B, 0x1B)), - Geometry = Geometry.Parse("F0 M24,24z M0,0z M4.41721,4.29873C4.35178,4.29873,4.29873,4.35178,4.29873,4.41721L4.29873,9.15646C4.29873,9.22189,4.35178,9.27494,4.41721,9.27494L9.15646,9.27494C9.22189,9.27494,9.27494,9.22189,9.27494,9.15646L9.27494,4.41721C9.27494,4.35178,9.22189,4.29873,9.15646,4.29873L4.41721,4.29873z M2.64,4.41721C2.64,3.43569,3.43569,2.64,4.41721,2.64L9.15646,2.64C10.138,2.64,10.9337,3.43569,10.9337,4.41721L10.9337,9.15646C10.9337,10.138,10.138,10.9337,9.15646,10.9337L4.41721,10.9337C3.43569,10.9337,2.64,10.138,2.64,9.15646L2.64,4.41721z M14.8435,4.29873C14.7781,4.29873,14.7251,4.35178,14.7251,4.41721L14.7251,9.15646C14.7251,9.22189,14.7781,9.27494,14.8435,9.27494L19.5828,9.27494C19.6482,9.27494,19.7013,9.22189,19.7013,9.15646L19.7013,4.41721C19.7013,4.35178,19.6482,4.29873,19.5828,4.29873L14.8435,4.29873z M13.0663,4.41721C13.0663,3.43569,13.862,2.64,14.8435,2.64L19.5828,2.64C20.5643,2.64,21.36,3.43569,21.36,4.41721L21.36,9.15646C21.36,10.138,20.5643,10.9337,19.5828,10.9337L14.8435,10.9337C13.862,10.9337,13.0663,10.138,13.0663,9.15646L13.0663,4.41721z M14.8435,14.7251C14.7781,14.7251,14.7251,14.7781,14.7251,14.8435L14.7251,19.5828C14.7251,19.6482,14.7781,19.7013,14.8435,19.7013L19.5828,19.7013C19.6482,19.7013,19.7013,19.6482,19.7013,19.5828L19.7013,14.8435C19.7013,14.7781,19.6482,14.7251,19.5828,14.7251L14.8435,14.7251z M13.0663,14.8435C13.0663,13.862,13.862,13.0663,14.8435,13.0663L19.5828,13.0663C20.5643,13.0663,21.36,13.862,21.36,14.8435L21.36,19.5828C21.36,20.5643,20.5643,21.36,19.5828,21.36L14.8435,21.36C13.862,21.36,13.0663,20.5643,13.0663,19.5828L13.0663,14.8435z M4.41721,14.7251C4.35178,14.7251,4.29873,14.7781,4.29873,14.8435L4.29873,19.5828C4.29873,19.6482,4.35178,19.7013,4.41721,19.7013L9.15646,19.7013C9.22189,19.7013,9.27494,19.6482,9.27494,19.5828L9.27494,14.8435C9.27494,14.7781,9.22189,14.7251,9.15646,14.7251L4.41721,14.7251z M2.64,14.8435C2.64,13.862,3.43569,13.0663,4.41721,13.0663L9.15646,13.0663C10.138,13.0663,10.9337,13.862,10.9337,14.8435L10.9337,19.5828C10.9337,20.5643,10.138,21.36,9.15646,21.36L4.41721,21.36C3.43569,21.36,2.64,20.5643,2.64,19.5828L2.64,14.8435z") - }; - - drawingGroup.Children.Add(geometryDrawing); - - // 设置图像源 - drawingImage.Drawing = drawingGroup; - image.Source = drawingImage; - - return image; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"创建图标图像时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - - // 返回一个空图像 - return new Image(); - } - } - - /// - /// 鼠标按下事件 - /// - private void Panel_MouseDown(object sender, MouseButtonEventArgs e) - { - try - { - // 提供反馈 - _panel.Background = new SolidColorBrush(Color.FromArgb(40, 0, 0, 0)); - LogHelper.WriteLogToFile("启动台按钮鼠标按下"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启动台按钮鼠标按下事件出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 鼠标抬起事件 - /// - private void Panel_MouseUp(object sender, MouseButtonEventArgs e) - { - try - { - // 只有左键点击才显示启动台窗口 - if (e.ChangedButton != MouseButton.Left) - { - return; - } - - // 恢复背景 - _panel.Background = Brushes.Transparent; - LogHelper.WriteLogToFile("启动台按钮鼠标抬起,准备显示启动台窗口"); - - // 获取按钮在屏幕上的位置 - Point buttonPosition = _panel.PointToScreen(new Point(_panel.ActualWidth / 2, 0)); - - // 显示启动台窗口 - _plugin.ShowLauncherWindow(buttonPosition); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启动台按钮鼠标抬起事件出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - /// - /// 鼠标离开事件 - /// - private void Panel_MouseLeave(object sender, MouseEventArgs e) - { - try - { - // 恢复背景 - _panel.Background = Brushes.Transparent; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启动台按钮鼠标离开事件出错: {ex.Message}", LogHelper.LogType.Error); - } - } - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs deleted file mode 100644 index 9b6ac63b..00000000 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherModels.cs +++ /dev/null @@ -1,332 +0,0 @@ -using Microsoft.Win32; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Drawing; -using System.IO; -using System.Runtime.InteropServices; -using System.Windows; -using System.Windows.Interop; -using System.Windows.Media; -using System.Windows.Media.Imaging; - -namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher -{ - /// - /// 启动台按钮位置 - /// - public enum LauncherButtonPosition - { - /// - /// 左侧 - /// - Left, - - /// - /// 右侧 - /// - Right - } - - /// - /// 启动台配置 - /// - public class LauncherConfig - { - /// - /// 启动台按钮位置 - /// - public LauncherButtonPosition ButtonPosition { get; set; } = LauncherButtonPosition.Right; - - /// - /// 启动台应用程序列表 - /// - public List Items { get; set; } = new List(); - } - - /// - /// 启动台应用项 - /// - public class LauncherItem - { - /// - /// 应用程序名称 - /// - public string Name { get; set; } - - /// - /// 应用程序路径 - /// - public string Path { get; set; } - - /// - /// 是否可见 - /// - public bool IsVisible { get; set; } = true; - - /// - /// 在启动台中的位置(0-39) - /// - public int Position { get; set; } = -1; - - /// - /// 是否已固定位置 - /// - public bool IsPositionFixed { get; set; } = false; - - /// - /// 图标缓存 - /// - [JsonIgnore] - private ImageSource _iconCache; - - /// - /// 获取应用程序图标 - /// - [JsonIgnore] - public ImageSource Icon - { - get - { - if (_iconCache != null) - { - return _iconCache; - } - - try - { - if (File.Exists(Path)) - { - // 从文件中获取图标 - Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(Path); - if (icon != null) - { - _iconCache = Imaging.CreateBitmapSourceFromHIcon( - icon.Handle, - Int32Rect.Empty, - BitmapSizeOptions.FromEmptyOptions()); - - icon.Dispose(); - return _iconCache; - } - } - else - { - // 从注册表中获取文件类型关联图标 - string extension = System.IO.Path.GetExtension(Path); - if (!string.IsNullOrEmpty(extension)) - { - string fileType = Registry.ClassesRoot.OpenSubKey(extension)?.GetValue(string.Empty) as string; - if (!string.IsNullOrEmpty(fileType)) - { - string iconPath = Registry.ClassesRoot.OpenSubKey(fileType + "\\DefaultIcon")?.GetValue(string.Empty) as string; - if (!string.IsNullOrEmpty(iconPath)) - { - string[] parts = iconPath.Split(','); - string iconFile = parts[0].Trim('"'); - int iconIndex = parts.Length > 1 ? Convert.ToInt32(parts[1]) : 0; - - if (File.Exists(iconFile)) - { - Icon icon = IconExtractor.Extract(iconFile, iconIndex, true); - if (icon != null) - { - _iconCache = Imaging.CreateBitmapSourceFromHIcon( - icon.Handle, - Int32Rect.Empty, - BitmapSizeOptions.FromEmptyOptions()); - - icon.Dispose(); - return _iconCache; - } - } - } - } - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"获取应用图标时出错: {ex.Message}", LogHelper.LogType.Error); - } - - // 返回默认图标 - return GetDefaultIcon(); - } - } - - /// - /// 获取默认图标 - /// - private ImageSource GetDefaultIcon() - { - try - { - // 对于资源管理器,使用特定图标 - if (Path.EndsWith("explorer.exe", StringComparison.OrdinalIgnoreCase)) - { - try - { - // 直接从C:\Windows\explorer.exe获取图标 - string explorerPath = @"C:\Windows\explorer.exe"; - if (File.Exists(explorerPath)) - { - Icon icon = System.Drawing.Icon.ExtractAssociatedIcon(explorerPath); - if (icon != null) - { - _iconCache = Imaging.CreateBitmapSourceFromHIcon( - icon.Handle, - Int32Rect.Empty, - BitmapSizeOptions.FromEmptyOptions()); - - icon.Dispose(); - return _iconCache; - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"获取资源管理器图标时出错: {ex.Message}", LogHelper.LogType.Warning); - // 如果获取Windows图标失败,回退到默认图标 - } - - // 回退到备用图标 - string explorerIconPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Icons-Fluent", "ic_fluent_folder_24_regular.png"); - if (File.Exists(explorerIconPath)) - { - Uri uri = new Uri(explorerIconPath); - BitmapImage image = new BitmapImage(uri); - _iconCache = image; - return _iconCache; - } - } - - // 返回一个简单的默认图标 - string iconPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Icons-png", "icc.png"); - if (File.Exists(iconPath)) - { - Uri uri = new Uri(iconPath); - BitmapImage image = new BitmapImage(uri); - _iconCache = image; - return _iconCache; - } - - // 如果还是没有找到,尝试使用应用程序图标 - string appIconPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "Icons-Fluent", "ic_fluent_apps_24_regular.png"); - if (File.Exists(appIconPath)) - { - Uri uri = new Uri(appIconPath); - BitmapImage image = new BitmapImage(uri); - _iconCache = image; - return _iconCache; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"获取默认图标时出错: {ex.Message}", LogHelper.LogType.Error); - } - - return null; - } - - /// - /// 启动应用程序 - /// - public void Launch() - { - try - { - if (string.IsNullOrEmpty(Path)) - { - LogHelper.WriteLogToFile("无法启动应用程序:路径为空", LogHelper.LogType.Error); - return; - } - - // 检查文件是否存在 - if (!File.Exists(Path) && !Path.Contains(":\\")) - { - // 可能是系统命令,如explorer.exe - ProcessStartInfo psi = new ProcessStartInfo - { - FileName = Path, - UseShellExecute = true - }; - Process.Start(psi); - } - else - { - // 使用Process.Start启动应用程序 - ProcessStartInfo psi = new ProcessStartInfo - { - FileName = Path, - UseShellExecute = true - }; - Process.Start(psi); - } - - LogHelper.WriteLogToFile($"已启动应用程序: {Path}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启动应用程序时出错: {ex.Message}", LogHelper.LogType.Error); - MessageBox.Show($"启动应用程序时出错: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - } - - /// - /// 图标提取工具类 - /// - public static class IconExtractor - { - /// - /// 从文件中提取图标 - /// - /// 文件路径 - /// 图标索引 - /// 是否提取大图标 - /// 提取的图标 - public static Icon Extract(string file, int index, bool largeIcon) - { - try - { - IntPtr large; - IntPtr small; - ExtractIconEx(file, index, out large, out small, 1); - - try - { - return Icon.FromHandle(largeIcon ? large : small); - } - catch - { - return null; - } - finally - { - if (large != IntPtr.Zero) - DestroyIcon(large); - - if (small != IntPtr.Zero) - DestroyIcon(small); - } - } - catch - { - return null; - } - } - - [DllImport("Shell32.dll", EntryPoint = "ExtractIconEx")] - private static extern int ExtractIconEx( - [MarshalAs(UnmanagedType.LPStr)] string lpszFile, - int nIconIndex, - out IntPtr phiconLarge, - out IntPtr phiconSmall, - int nIcons); - - [DllImport("User32.dll")] - private static extern int DestroyIcon(IntPtr hIcon); - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml deleted file mode 100644 index dde23f42..00000000 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherSettingsControl.xaml +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs deleted file mode 100644 index 6ca80e90..00000000 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncher/LauncherWindow.xaml.cs +++ /dev/null @@ -1,466 +0,0 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Input; -using System.Windows.Media; -using System.Windows.Threading; - -namespace Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher -{ - /// - /// LauncherWindow.xaml 的交互逻辑 - /// - public partial class LauncherWindow : Window - { - /// - /// 父插件 - /// - private readonly SuperLauncherPlugin _plugin; - - /// - /// 是否处于固定模式 - /// - private bool _isFixMode; - - /// - /// 应用项按钮列表 - /// - private readonly Dictionary _appButtons = new Dictionary(); - - /// - /// 拖拽中的按钮 - /// - private Button _draggingButton; - - /// - /// 拖拽开始位置 - /// - private Point _dragStartPoint; - - /// - /// 构造函数 - /// - public LauncherWindow(SuperLauncherPlugin plugin) - { - InitializeComponent(); - - _plugin = plugin; - - // 加载应用项 - LoadLauncherItems(); - - // 添加鼠标按下事件(用于拖动窗口) - MouseDown += (s, e) => - { - if (e.ChangedButton == MouseButton.Left && e.ButtonState == MouseButtonState.Pressed) - { - DragMove(); - } - }; - - // 根据应用数量调整窗口大小 - AdjustWindowSize(); - } - - /// - /// 加载启动台应用项 - /// - private void LoadLauncherItems() - { - // 清空现有应用项 - AppPanel.Children.Clear(); - _appButtons.Clear(); - - // 获取显示的应用项 - var visibleItems = _plugin.LauncherItems - .Where(item => item.IsVisible) - .OrderBy(item => item.Position) - .ToList(); - - foreach (var item in visibleItems) - { - // 创建应用按钮 - Button appButton = new Button - { - Style = (Style)FindResource("LauncherItemStyle"), - DataContext = item, - Tag = item.Position - }; - - // 添加点击事件 - appButton.Click += AppButton_Click; - - // 在固定模式下,添加拖拽事件 - appButton.PreviewMouseDown += AppButton_PreviewMouseDown; - appButton.PreviewMouseMove += AppButton_PreviewMouseMove; - appButton.PreviewMouseUp += AppButton_PreviewMouseUp; - - // 记录按钮和项目的对应关系 - _appButtons.Add(appButton, item); - - // 添加到面板 - AppPanel.Children.Add(appButton); - } - } - - /// - /// 根据应用数量调整窗口大小 - /// - private void AdjustWindowSize() - { - try - { - // 每行最多显示4个应用 - const int appsPerRow = 4; - - // 计算行数 - int visibleCount = _appButtons.Count; - int rowCount = (int)Math.Ceiling(visibleCount / (double)appsPerRow); - - // 设置窗口宽度(每个应用90像素宽 = 80 + 5*2) - Width = Math.Min(appsPerRow * 90 + 40, 400); // 最大宽度400 - - // 设置窗口高度(每个应用90像素高 = 80 + 5*2) - Height = Math.Min(rowCount * 90 + 60, 600); // 最大高度600,标题栏40 + 边距20 - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"调整启动台窗口大小时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 应用按钮点击事件 - /// - private void AppButton_Click(object sender, RoutedEventArgs e) - { - try - { - if (_isFixMode) return; // 在固定模式下,不响应点击事件 - - if (sender is Button button && _appButtons.TryGetValue(button, out LauncherItem item)) - { - // 获取应用路径和名称,用于后续启动 - string appPath = item.Path; - string appName = item.Name; - - LogHelper.WriteLogToFile($"点击启动应用: {appName}, 路径: {appPath}"); - - // 首先标记窗口正在关闭 - IsClosing = true; - - // 创建一个应用启动任务 - var launchTask = new Task(() => - { - try - { - // 等待一段时间,确保窗口关闭流程已经开始 - Thread.Sleep(200); - - // 使用UI线程启动应用 - Application.Current.Dispatcher.Invoke(() => - { - try - { - // 检查应用路径是否存在 - if (File.Exists(appPath) || !appPath.Contains(":\\")) - { - // 创建进程启动信息 - var psi = new ProcessStartInfo - { - FileName = appPath, - UseShellExecute = true, - }; - - // 启动应用程序 - var process = Process.Start(psi); - LogHelper.WriteLogToFile($"应用程序 {appName} 已启动"); - } - else - { - LogHelper.WriteLogToFile($"应用路径不存在: {appPath}", LogHelper.LogType.Error); - MessageBox.Show($"找不到应用程序: {appPath}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启动应用程序失败: {ex.Message}", LogHelper.LogType.Error); - MessageBox.Show($"启动应用程序失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error); - } - }); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"应用启动任务出错: {ex.Message}", LogHelper.LogType.Error); - } - }); - - // 关闭窗口 - try - { - Dispatcher.BeginInvoke(new Action(() => - { - try { Close(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } - - // 启动应用程序任务 - launchTask.Start(); - }), DispatcherPriority.Background); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"关闭窗口或启动任务时出错: {ex.Message}", LogHelper.LogType.Error); - // 如果无法通过UI关闭窗口,直接启动任务 - launchTask.Start(); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"应用按钮点击事件出错: {ex.Message}", LogHelper.LogType.Error); - try { IsClosing = true; Close(); } catch (Exception innerEx) { System.Diagnostics.Debug.WriteLine(innerEx); } - } - } - - #region 固定模式拖拽事件 - - /// - /// 应用按钮鼠标按下事件 - /// - private void AppButton_PreviewMouseDown(object sender, MouseButtonEventArgs e) - { - if (!_isFixMode) return; - - if (e.ChangedButton == MouseButton.Left && sender is Button button) - { - _draggingButton = button; - _dragStartPoint = e.GetPosition(AppPanel); - button.CaptureMouse(); - button.Opacity = 0.7; - - // 阻止事件冒泡,以避免触发按钮点击 - e.Handled = true; - } - } - - /// - /// 应用按钮鼠标移动事件 - /// - private void AppButton_PreviewMouseMove(object sender, MouseEventArgs e) - { - if (!_isFixMode || _draggingButton == null) return; - - if (e.LeftButton == MouseButtonState.Pressed) - { - Point currentPosition = e.GetPosition(AppPanel); - - // 移动按钮 - System.Windows.Controls.Canvas.SetLeft(_draggingButton, currentPosition.X - _draggingButton.ActualWidth / 2); - System.Windows.Controls.Canvas.SetTop(_draggingButton, currentPosition.Y - _draggingButton.ActualHeight / 2); - - // 将按钮移到最上层 - Panel.SetZIndex(_draggingButton, 100); - - // 阻止事件冒泡 - e.Handled = true; - } - } - - /// - /// 应用按钮鼠标释放事件 - /// - private void AppButton_PreviewMouseUp(object sender, MouseButtonEventArgs e) - { - if (!_isFixMode || _draggingButton == null) return; - - // 释放鼠标捕获 - _draggingButton.ReleaseMouseCapture(); - - // 计算新位置 - Point releasePoint = e.GetPosition(AppPanel); - int newPosition = CalculateGridPosition(releasePoint); - - // 获取当前项目 - LauncherItem currentItem = _appButtons[_draggingButton]; - - // 重新排序 - ReorderItems(currentItem, newPosition); - - // 重新加载应用项 - LoadLauncherItems(); - - // 保存配置 - _plugin.SaveConfig(); - - // 清除拖拽状态 - _draggingButton.Opacity = 1; - Panel.SetZIndex(_draggingButton, 0); - _draggingButton = null; - - // 阻止事件冒泡 - e.Handled = true; - } - - /// - /// 计算网格位置 - /// - private int CalculateGridPosition(Point point) - { - // 计算行和列 - int columnCount = 4; // 每行最多4个应用 - int columnWidth = 90; // 应用宽度(包括边距) - int rowHeight = 90; // 应用高度(包括边距) - - int column = (int)(point.X / columnWidth); - int row = (int)(point.Y / rowHeight); - - // 确保在有效范围内 - column = Math.Max(0, Math.Min(column, columnCount - 1)); - row = Math.Max(0, row); - - // 计算位置索引 - return row * columnCount + column; - } - - /// - /// 重新排序应用项 - /// - private void ReorderItems(LauncherItem item, int newPosition) - { - try - { - // 设置项目为固定位置 - item.IsPositionFixed = true; - - // 如果位置相同,无需调整 - if (item.Position == newPosition) - { - return; - } - - // 获取所有可见项目 - var visibleItems = _plugin.LauncherItems - .Where(i => i.IsVisible) - .OrderBy(i => i.Position) - .ToList(); - - // 移除当前项目 - visibleItems.Remove(item); - - // 查找插入位置 - int insertIndex = 0; - for (int i = 0; i < visibleItems.Count; i++) - { - if (visibleItems[i].Position >= newPosition) - { - insertIndex = i; - break; - } - insertIndex = i + 1; - } - - // 插入项目 - visibleItems.Insert(insertIndex, item); - - // 重新分配位置 - for (int i = 0; i < visibleItems.Count; i++) - { - visibleItems[i].Position = i; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重新排序应用项时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 窗口事件处理 - - /// - /// 窗口失去焦点事件 - /// - private void Window_Deactivated(object sender, EventArgs e) - { - try - { - // 只有在非固定模式、窗口已加载、未处于关闭状态且IsLoaded=true时关闭窗口 - if (!_isFixMode && IsLoaded && !IsClosing) - { - // 标记为正在关闭 - IsClosing = true; - - // 使用Dispatcher.BeginInvoke而不是直接调用Close,避免冲突 - Dispatcher.BeginInvoke(new Action(() => - { - try - { - // 再次检查窗口状态 - if (IsLoaded && !IsClosing) - { - Close(); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"延迟关闭窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - }), DispatcherPriority.Background); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"窗口失去焦点关闭时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 窗口是否正在关闭 - /// - private bool IsClosing { get; set; } - - /// - /// 重写OnClosing方法,标记窗口正在关闭 - /// - protected override void OnClosing(CancelEventArgs e) - { - IsClosing = true; - base.OnClosing(e); - } - - /// - /// 关闭按钮点击事件 - /// - private void BtnClose_Click(object sender, RoutedEventArgs e) - { - Close(); - } - - /// - /// 固定模式按钮点击事件 - /// - private void BtnFixMode_Click(object sender, RoutedEventArgs e) - { - // 切换固定模式 - _isFixMode = !_isFixMode; - - // 更新固定模式按钮图标颜色 - FixModeIcon.Fill = _isFixMode ? Brushes.Yellow : Brushes.White; - - // 显示提示 - if (_isFixMode) - { - MessageBox.Show("已进入固定模式,您可以拖动应用图标调整位置。", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs b/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs deleted file mode 100644 index 555c7bf9..00000000 --- a/Ink Canvas/Helpers/Plugins/BuiltIn/SuperLauncherPlugin.cs +++ /dev/null @@ -1,589 +0,0 @@ -using Ink_Canvas.Helpers.Plugins.BuiltIn.SuperLauncher; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace Ink_Canvas.Helpers.Plugins.BuiltIn -{ - /// - /// 超级启动台插件 - /// - public class SuperLauncherPlugin : PluginBase - { - #region 插件基本信息 - - public override string Name => "超级启动台"; - - public override string Description => "在浮动栏添加一个启动台按钮,可快速启动常用应用程序。"; - - public override Version Version => new Version(1, 0, 1); - - public override string Author => "ICC CE 团队"; - - public override bool IsBuiltIn => true; - - #endregion - - #region 插件属性和字段 - - /// - /// 启动台配置 - /// - public LauncherConfig Config { get; private set; } - - /// - /// 启动台应用程序列表 - /// - public ObservableCollection LauncherItems { get; private set; } - - /// - /// 启动台按钮 - /// - private LauncherButton _launcherButton; - - /// - /// 启动台窗口 - /// - private LauncherWindow _launcherWindow; - - /// - /// 配置文件路径 - /// - private readonly string _configPath = Path.Combine(App.RootPath, "PluginConfigs", "SuperLauncher.json"); - - /// - /// 标记是否已添加到浮动栏 - /// - private bool _isAddedToFloatingBar; - - #endregion - - #region 插件生命周期 - - public override void Initialize() - { - try - { - base.Initialize(); - - // 创建配置目录 - string configDir = Path.Combine(App.RootPath, "PluginConfigs"); - if (!Directory.Exists(configDir)) - { - Directory.CreateDirectory(configDir); - } - - // 加载配置 - LoadConfig(); - - LogHelper.WriteLogToFile("超级启动台插件已初始化"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"初始化超级启动台插件时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - public override void Enable() - { - try - { - if (IsEnabled) return; // 防止重复启用 - - // 创建启动台按钮 - if (_launcherButton == null) - { - _launcherButton = new LauncherButton(this); - LogHelper.WriteLogToFile("超级启动台按钮已创建"); - } - - // 添加启动台按钮到浮动栏 - AddLauncherButtonToFloatingBar(); - - // 设置启用状态 - base.Enable(); - - // 保存插件配置 - SavePluginSettings(); - - LogHelper.WriteLogToFile("超级启动台插件已启用"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启用超级启动台插件时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - public override void Disable() - { - try - { - if (!IsEnabled) return; // 防止重复禁用 - - // 从浮动栏移除启动台按钮 - RemoveLauncherButtonFromFloatingBar(); - - // 如果启动台窗口打开,则关闭 - if (_launcherWindow != null && _launcherWindow.IsVisible) - { - _launcherWindow.Close(); - _launcherWindow = null; - } - - // 设置禁用状态 - base.Disable(); - - // 保存插件配置 - SavePluginSettings(); - - LogHelper.WriteLogToFile("超级启动台插件已禁用"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"禁用超级启动台插件时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - public override UserControl GetSettingsView() - { - return new LauncherSettingsControl(this); - } - - public override void Cleanup() - { - // 保存配置 - SaveConfig(); - - // 从浮动栏移除启动台按钮 - RemoveLauncherButtonFromFloatingBar(); - - // 如果启动台窗口打开,则关闭 - if (_launcherWindow != null && _launcherWindow.IsVisible) - { - _launcherWindow.Close(); - _launcherWindow = null; - } - - base.Cleanup(); - } - - /// - /// 保存插件设置 - /// - public override void SavePluginSettings() - { - try - { - // 确保配置已加载 - if (Config == null) - { - LoadConfig(); - } - - // 更新其他设置,但不更改插件启用状态 - - // 保存配置 - SaveConfig(); - - LogHelper.WriteLogToFile("超级启动台插件设置已保存"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"保存超级启动台插件设置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 配置管理 - - /// - /// 加载配置 - /// - private void LoadConfig() - { - try - { - if (File.Exists(_configPath)) - { - string json = File.ReadAllText(_configPath); - Config = JsonConvert.DeserializeObject(json) ?? CreateDefaultConfig(); - LauncherItems = new ObservableCollection(Config.Items ?? new List()); - - // 注意:不再根据配置更改插件启用状态 - // 插件状态由PluginManager统一管理 - } - else - { - Config = CreateDefaultConfig(); - LauncherItems = new ObservableCollection(Config.Items); - SaveConfig(); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载超级启动台配置时出错: {ex.Message}", LogHelper.LogType.Error); - Config = CreateDefaultConfig(); - LauncherItems = new ObservableCollection(Config.Items); - } - } - - /// - /// 保存配置 - /// - public void SaveConfig() - { - try - { - // 同步LauncherItems到Config - Config.Items = new List(LauncherItems); - - // 序列化并保存配置 - string json = JsonConvert.SerializeObject(Config, Formatting.Indented); - File.WriteAllText(_configPath, json); - - LogHelper.WriteLogToFile("超级启动台配置已保存"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"保存超级启动台配置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 创建默认配置 - /// - private LauncherConfig CreateDefaultConfig() - { - var config = new LauncherConfig - { - ButtonPosition = LauncherButtonPosition.Right, - // 不再使用IsEnabled,插件状态由PluginManager管理 - Items = new List - { - new LauncherItem - { - Name = "资源管理器", - Path = @"C:\Windows\explorer.exe", - IsVisible = true, - Position = 0 - } - } - }; - - return config; - } - - #endregion - - #region 启动台按钮管理 - - /// - /// 将启动台按钮添加到浮动栏 - /// - private void AddLauncherButtonToFloatingBar() - { - try - { - // 如果已经添加,先移除 - if (_isAddedToFloatingBar) - { - RemoveLauncherButtonFromFloatingBar(); - _isAddedToFloatingBar = false; - } - - // 获取主窗口实例 - var mainWindow = Application.Current.MainWindow; - if (mainWindow == null) - { - LogHelper.WriteLogToFile("未找到主窗口实例,无法添加启动台按钮", LogHelper.LogType.Error); - return; - } - - // 创建启动台按钮 - _launcherButton = new LauncherButton(this); - var buttonElement = _launcherButton.Element; - - // 查找浮动栏 - var floatingBar = mainWindow.FindName("StackPanelFloatingBar") as Panel; - if (floatingBar == null) - { - // 如果直接查找失败,则尝试遍历可视树查找 - Panel floatingBarPanelFromTree = null; - FindStackPanelFloatingBar(mainWindow, ref floatingBarPanelFromTree); - floatingBar = floatingBarPanelFromTree; - } - - if (floatingBar == null) - { - LogHelper.WriteLogToFile("未找到浮动栏,无法添加启动台按钮", LogHelper.LogType.Error); - return; - } - - // 添加启动台按钮到浮动栏 - if (Config.ButtonPosition == LauncherButtonPosition.Left) - { - floatingBar.Children.Insert(0, buttonElement); - LogHelper.WriteLogToFile("启动台按钮已添加到浮动栏左侧"); - } - else - { - floatingBar.Children.Add(buttonElement); - LogHelper.WriteLogToFile("启动台按钮已添加到浮动栏右侧"); - } - - _isAddedToFloatingBar = true; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"添加启动台按钮到浮动栏时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - /// - /// 递归查找StackPanelFloatingBar - /// - private void FindStackPanelFloatingBar(DependencyObject parent, ref Panel result) - { - if (parent == null || result != null) return; - - try - { - // 检查当前对象是否为我们要找的面板 - if (parent is Panel panel && panel.Name == "StackPanelFloatingBar") - { - result = panel; - return; - } - - // 获取子元素数量 - int childCount = VisualTreeHelper.GetChildrenCount(parent); - - // 遍历所有子元素 - for (int i = 0; i < childCount; i++) - { - DependencyObject child = VisualTreeHelper.GetChild(parent, i); - FindStackPanelFloatingBar(child, ref result); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"查找StackPanelFloatingBar时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 从浮动栏移除启动台按钮 - /// - private void RemoveLauncherButtonFromFloatingBar() - { - try - { - if (!_isAddedToFloatingBar || _launcherButton == null) - { - return; - } - - // 获取主窗口实例 - var mainWindow = Application.Current.MainWindow; - if (mainWindow == null) - { - LogHelper.WriteLogToFile("未找到主窗口实例,无法移除启动台按钮", LogHelper.LogType.Error); - return; - } - - // 获取按钮元素 - var buttonElement = _launcherButton.Element; - - // 查找浮动栏 - var floatingBar = mainWindow.FindName("StackPanelFloatingBar") as Panel; - if (floatingBar == null) - { - // 如果直接查找失败,则尝试遍历可视树查找 - Panel floatingBarPanelFromTree = null; - FindStackPanelFloatingBar(mainWindow, ref floatingBarPanelFromTree); - floatingBar = floatingBarPanelFromTree; - } - - if (floatingBar == null) - { - LogHelper.WriteLogToFile("未找到浮动栏,无法移除启动台按钮", LogHelper.LogType.Error); - return; - } - - // 从浮动栏移除启动台按钮 - if (floatingBar.Children.Contains(buttonElement)) - { - floatingBar.Children.Remove(buttonElement); - LogHelper.WriteLogToFile("启动台按钮已从浮动栏移除"); - } - - _isAddedToFloatingBar = false; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"移除启动台按钮时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - /// - /// 更新启动台按钮位置 - /// - public void UpdateButtonPosition() - { - try - { - // 如果按钮已添加到浮动栏,重新添加以更新位置 - if (_isAddedToFloatingBar) - { - RemoveLauncherButtonFromFloatingBar(); - AddLauncherButtonToFloatingBar(); - LogHelper.WriteLogToFile($"启动台按钮位置已更新为: {Config.ButtonPosition}"); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"更新启动台按钮位置时出错: {ex.Message}", LogHelper.LogType.Error); - LogHelper.NewLog(ex); - } - } - - #endregion - - #region 启动台功能 - - /// - /// 显示启动台窗口 - /// - /// 按钮在屏幕上的位置 - public void ShowLauncherWindow(Point buttonPosition) - { - try - { - // 如果窗口已存在,关闭它 - if (_launcherWindow != null && _launcherWindow.IsVisible) - { - _launcherWindow.Close(); - _launcherWindow = null; - return; - } - - // 创建新的启动台窗口 - _launcherWindow = new LauncherWindow(this); - - // 计算窗口位置,使其位于按钮上方 - PositionLauncherWindow(_launcherWindow, buttonPosition); - - // 显示窗口 - _launcherWindow.Show(); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示启动台窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 设置启动台窗口位置 - /// - /// 启动台窗口 - /// 按钮在屏幕上的位置 - private void PositionLauncherWindow(LauncherWindow window, Point buttonPosition) - { - // 确保窗口已加载 - if (window.ActualWidth == 0 || window.ActualHeight == 0) - { - window.WindowStartupLocation = WindowStartupLocation.CenterScreen; - - // 设置窗口加载完成后的位置 - window.Loaded += (s, e) => - { - // 窗口位于按钮上方居中 - double left = buttonPosition.X - (window.ActualWidth / 2); - double top = buttonPosition.Y - window.ActualHeight - 10; // 在按钮上方留出一些间距 - - // 确保窗口在屏幕内 - left = Math.Max(0, Math.Min(left, SystemParameters.WorkArea.Width - window.ActualWidth)); - top = Math.Max(0, Math.Min(top, SystemParameters.WorkArea.Height - window.ActualHeight)); - - window.Left = left; - window.Top = top; - }; - } - else - { - // 窗口位于按钮上方居中 - double left = buttonPosition.X - (window.ActualWidth / 2); - double top = buttonPosition.Y - window.ActualHeight - 10; // 在按钮上方留出一些间距 - - // 确保窗口在屏幕内 - left = Math.Max(0, Math.Min(left, SystemParameters.WorkArea.Width - window.ActualWidth)); - top = Math.Max(0, Math.Min(top, SystemParameters.WorkArea.Height - window.ActualHeight)); - - window.Left = left; - window.Top = top; - } - } - - /// - /// 添加应用到启动台 - /// - /// 启动台项 - public void AddLauncherItem(LauncherItem item) - { - // 如果项目数量已达上限,则不添加 - if (LauncherItems.Count >= 40) - { - MessageBox.Show("启动台项目数量已达上限(40个)!", "提示", MessageBoxButton.OK, MessageBoxImage.Information); - return; - } - - // 寻找合适的位置 - if (item.Position < 0) - { - item.Position = FindNextAvailablePosition(); - } - - // 添加项目并保存配置 - LauncherItems.Add(item); - SaveConfig(); - } - - /// - /// 查找下一个可用位置 - /// - private int FindNextAvailablePosition() - { - // 获取已使用的位置列表 - var usedPositions = new HashSet(); - foreach (var item in LauncherItems) - { - usedPositions.Add(item.Position); - } - - // 查找第一个可用位置 - for (int i = 0; i < 40; i++) - { - if (!usedPositions.Contains(i)) - { - return i; - } - } - - // 如果所有位置都已使用,则返回0 - return 0; - } - - #endregion - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IActionService.cs b/Ink Canvas/Helpers/Plugins/IActionService.cs deleted file mode 100644 index 99c61473..00000000 --- a/Ink Canvas/Helpers/Plugins/IActionService.cs +++ /dev/null @@ -1,296 +0,0 @@ -using System; -using System.Windows.Media; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 操作服务接口,统一所有执行操作相关的方法 - /// - public interface IActionService - { - #region 画布操作 - - /// - /// 清除当前画布 - /// - void ClearCanvas(); - - /// - /// 清除所有画布 - /// - void ClearAllCanvases(); - - /// - /// 添加新页面 - /// - void AddNewPage(); - - /// - /// 删除当前页面 - /// - void DeleteCurrentPage(); - - /// - /// 切换到指定页面 - /// - /// 页面索引 - void SwitchToPage(int pageIndex); - - /// - /// 切换到下一页 - /// - void NextPage(); - - /// - /// 切换到上一页 - /// - void PreviousPage(); - - #endregion - - #region 绘制操作 - - /// - /// 设置绘制模式 - /// - /// 绘制模式 - void SetDrawingMode(int mode); - - /// - /// 设置笔触宽度 - /// - /// 宽度 - void SetInkWidth(double width); - - /// - /// 设置笔触颜色 - /// - /// 颜色 - void SetInkColor(Color color); - - /// - /// 设置高亮笔宽度 - /// - /// 宽度 - void SetHighlighterWidth(double width); - - /// - /// 设置橡皮擦大小 - /// - /// 大小 - void SetEraserSize(int size); - - /// - /// 设置橡皮擦类型 - /// - /// 类型 - void SetEraserType(int type); - - /// - /// 设置橡皮擦形状 - /// - /// 形状 - void SetEraserShape(int shape); - - /// - /// 设置笔触透明度 - /// - /// 透明度 - void SetInkAlpha(double alpha); - - /// - /// 设置笔触样式 - /// - /// 样式 - void SetInkStyle(int style); - - /// - /// 设置背景颜色 - /// - /// 颜色 - void SetBackgroundColor(string color); - - #endregion - - #region 文件操作 - - /// - /// 保存画布内容 - /// - /// 文件路径 - void SaveCanvas(string filePath); - - /// - /// 加载画布内容 - /// - /// 文件路径 - void LoadCanvas(string filePath); - - /// - /// 导出为图片 - /// - /// 文件路径 - /// 图片格式 - void ExportAsImage(string filePath, string format); - - /// - /// 导出为PDF - /// - /// 文件路径 - void ExportAsPDF(string filePath); - - #endregion - - #region 撤销重做操作 - - /// - /// 撤销操作 - /// - void Undo(); - - /// - /// 重做操作 - /// - void Redo(); - - #endregion - - #region 选择操作 - - /// - /// 全选 - /// - void SelectAll(); - - /// - /// 取消选择 - /// - void DeselectAll(); - - /// - /// 删除选中内容 - /// - void DeleteSelected(); - - /// - /// 复制选中内容 - /// - void CopySelected(); - - /// - /// 剪切选中内容 - /// - void CutSelected(); - - /// - /// 粘贴内容 - /// - void Paste(); - - #endregion - - #region 系统设置操作 - - /// - /// 设置系统设置 - /// - /// 设置类型 - /// 设置键 - /// 设置值 - void SetSetting(string key, T value); - - /// - /// 保存设置到文件 - /// - void SaveSettings(); - - /// - /// 从文件加载设置 - /// - void LoadSettings(); - - /// - /// 重置设置为默认值 - /// - void ResetSettings(); - - #endregion - - #region 插件管理操作 - - /// - /// 启用插件 - /// - /// 插件名称 - void EnablePlugin(string pluginName); - - /// - /// 禁用插件 - /// - /// 插件名称 - void DisablePlugin(string pluginName); - - /// - /// 卸载插件 - /// - /// 插件名称 - void UnloadPlugin(string pluginName); - - #endregion - - #region 事件系统操作 - - /// - /// 注册事件处理器 - /// - /// 事件名称 - /// 事件处理器 - void RegisterEventHandler(string eventName, EventHandler handler); - - /// - /// 注销事件处理器 - /// - /// 事件名称 - /// 事件处理器 - void UnregisterEventHandler(string eventName, EventHandler handler); - - /// - /// 触发事件 - /// - /// 事件名称 - /// 事件发送者 - /// 事件参数 - void TriggerEvent(string eventName, object sender, EventArgs args); - - #endregion - - #region 应用程序操作 - - /// - /// 重启应用程序 - /// - void RestartApplication(); - - /// - /// 退出应用程序 - /// - void ExitApplication(); - - /// - /// 检查更新 - /// - void CheckForUpdates(); - - /// - /// 打开帮助文档 - /// - void OpenHelpDocument(); - - /// - /// 打开关于页面 - /// - void OpenAboutPage(); - - #endregion - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs b/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs deleted file mode 100644 index 4287225d..00000000 --- a/Ink Canvas/Helpers/Plugins/ICCPPPluginAdapter.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System; -using System.IO; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// ICCPP 插件适配器,用于加载和管理 .iccpp 格式的插件 - /// - public class ICCPPPluginAdapter : PluginBase - { - private readonly byte[] _pluginData; - private readonly string _pluginPath; - private readonly string _pluginName; - private readonly Version _pluginVersion; - private bool _isInitialized; - - public override string PluginStateKey => "ICCPP:" + (_pluginPath ?? string.Empty); - - /// - /// 创建 ICCPP 插件适配器 - /// - /// 插件文件路径 - /// 插件文件数据 - public ICCPPPluginAdapter(string pluginPath, byte[] pluginData) - { - _pluginPath = pluginPath; - _pluginData = pluginData; - PluginPath = pluginPath; - - // 从文件名获取插件名称 - _pluginName = Path.GetFileNameWithoutExtension(pluginPath); - _pluginVersion = new Version(1, 0, 0); // 默认版本 - - // 尝试从插件数据中读取更多信息 - TryReadPluginMetadata(); - } - - public ICCPPPluginAdapter() - { - _pluginPath = string.Empty; - _pluginData = new byte[0]; - PluginPath = string.Empty; - _pluginName = "ICCPPPlugin"; - _pluginVersion = new Version(1, 0, 0); - // 可选:初始化其他字段 - } - - /// - /// 尝试从插件数据中读取元数据 - /// - private void TryReadPluginMetadata() - { - try - { - // 这里可以根据 .iccpp 文件的实际格式解析元数据 - // 例如,如果文件有特定的头部结构,可以在这里解析 - - // 示例:如果前100字节包含元数据 - if (_pluginData.Length > 100) - { - // 解析元数据的代码... - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"解析插件 {_pluginName} 元数据时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #region IPlugin 接口实现 - - /// - /// 插件名称 - /// - public override string Name => _pluginName; - - /// - /// 插件描述 - /// - public override string Description => $"{_pluginName} (ICCPP 格式插件)"; - - /// - /// 插件版本 - /// - public override Version Version => _pluginVersion; - - /// - /// 插件作者 - /// - public override string Author => "未知"; - - /// - /// 是否为内置插件 - /// - public override bool IsBuiltIn => false; - - /// - /// 初始化插件 - /// - public override void Initialize() - { - if (_isInitialized) return; - - try - { - // 这里可以添加 .iccpp 插件的初始化逻辑 - // 例如,根据文件格式加载特定资源 - - LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已初始化"); - _isInitialized = true; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"初始化 ICCPP 插件 {Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 启用插件 - /// - public override void Enable() - { - if (IsEnabled) return; - - try - { - // 这里可以添加 .iccpp 插件的启用逻辑 - // 例如,加载动态库、注册事件等 - - base.Enable(); // 设置启用状态并触发事件 - LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已启用"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启用 ICCPP 插件 {Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 禁用插件 - /// - public override void Disable() - { - if (!IsEnabled) return; - - try - { - // 这里可以添加 .iccpp 插件的禁用逻辑 - // 例如,卸载动态库、注销事件等 - - base.Disable(); // 设置禁用状态并触发事件 - LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已禁用"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"禁用 ICCPP 插件 {Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 清理插件资源 - /// - public override void Cleanup() - { - try - { - // 这里可以添加 .iccpp 插件的清理逻辑 - // 例如,释放资源等 - - LogHelper.WriteLogToFile($"ICCPP 插件 {Name} 已清理资源"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"清理 ICCPP 插件 {Name} 资源时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IGetService.cs b/Ink Canvas/Helpers/Plugins/IGetService.cs deleted file mode 100644 index 60f299ba..00000000 --- a/Ink Canvas/Helpers/Plugins/IGetService.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System.Collections.Generic; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 获取服务接口,统一所有获取类的方法 - /// - public interface IGetService - { - #region 窗口和UI获取 - - /// - /// 获取主窗口引用 - /// - Window MainWindow { get; } - - /// - /// 获取当前画布 - /// - global::System.Windows.Controls.InkCanvas CurrentCanvas { get; } - - /// - /// 获取所有画布页面 - /// - List AllCanvasPages { get; } - - /// - /// 获取当前页面索引 - /// - int CurrentPageIndex { get; } - - /// - /// 获取当前页面数量 - /// - int TotalPageCount { get; } - - /// - /// 获取浮动工具栏 - /// - FrameworkElement FloatingToolBar { get; } - - /// - /// 获取左侧面板 - /// - FrameworkElement LeftPanel { get; } - - /// - /// 获取右侧面板 - /// - FrameworkElement RightPanel { get; } - - /// - /// 获取顶部面板 - /// - FrameworkElement TopPanel { get; } - - /// - /// 获取底部面板 - /// - FrameworkElement BottomPanel { get; } - - #endregion - - #region 绘制工具状态获取 - - /// - /// 获取当前绘制模式 - /// - int CurrentDrawingMode { get; } - - /// - /// 获取当前笔触宽度 - /// - double CurrentInkWidth { get; } - - /// - /// 获取当前笔触颜色 - /// - Color CurrentInkColor { get; } - - /// - /// 获取当前高亮笔宽度 - /// - double CurrentHighlighterWidth { get; } - - /// - /// 获取当前橡皮擦大小 - /// - int CurrentEraserSize { get; } - - /// - /// 获取当前橡皮擦类型 - /// - int CurrentEraserType { get; } - - /// - /// 获取当前橡皮擦形状 - /// - int CurrentEraserShape { get; } - - /// - /// 获取当前笔触透明度 - /// - double CurrentInkAlpha { get; } - - /// - /// 获取当前笔触样式 - /// - int CurrentInkStyle { get; } - - /// - /// 获取当前背景颜色 - /// - string CurrentBackgroundColor { get; } - - #endregion - - #region 应用状态获取 - - /// - /// 获取当前主题模式 - /// - bool IsDarkTheme { get; } - - /// - /// 获取当前是否为白板模式 - /// - bool IsWhiteboardMode { get; } - - /// - /// 获取当前是否为PPT模式 - /// - bool IsPPTMode { get; } - - /// - /// 获取当前是否为全屏模式 - /// - bool IsFullScreenMode { get; } - - /// - /// 获取当前是否为画板模式 - /// - bool IsCanvasMode { get; } - - /// - /// 获取当前是否为选择模式 - /// - bool IsSelectionMode { get; } - - /// - /// 获取当前是否为擦除模式 - /// - bool IsEraserMode { get; } - - /// - /// 获取当前是否为形状绘制模式 - /// - bool IsShapeDrawingMode { get; } - - /// - /// 获取当前是否为高亮模式 - /// - bool IsHighlighterMode { get; } - - #endregion - - #region 撤销重做状态获取 - - /// - /// 获取是否可以撤销 - /// - bool CanUndo { get; } - - /// - /// 获取是否可以重做 - /// - bool CanRedo { get; } - - #endregion - - #region 系统设置获取 - - /// - /// 获取系统设置 - /// - /// 设置类型 - /// 设置键 - /// 默认值 - /// 设置值 - T GetSetting(string key, T defaultValue = default(T)); - - #endregion - - #region 插件信息获取 - - /// - /// 获取所有已加载的插件 - /// - /// 插件列表 - List GetAllPlugins(); - - /// - /// 获取指定插件 - /// - /// 插件名称 - /// 插件实例 - IPlugin GetPlugin(string pluginName); - - #endregion - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IPlugin.cs b/Ink Canvas/Helpers/Plugins/IPlugin.cs deleted file mode 100644 index 0a43ab15..00000000 --- a/Ink Canvas/Helpers/Plugins/IPlugin.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Windows.Controls; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 定义插件的基本接口 - /// - public interface IPlugin - { - /// - /// 插件名称 - /// - string Name { get; } - - /// - /// 插件描述 - /// - string Description { get; } - - /// - /// 插件版本 - /// - Version Version { get; } - - /// - /// 插件作者 - /// - string Author { get; } - - /// - /// 是否为内置插件 - /// - bool IsBuiltIn { get; } - - /// - /// 初始化插件 - /// 此方法在插件加载时被调用,用于执行一些初始化工作 - /// - void Initialize(); - - /// - /// 启用插件 - /// 此方法在插件被用户或系统启用时调用,激活插件功能 - /// - void Enable(); - - /// - /// 禁用插件 - /// 此方法在插件被用户或系统禁用时调用,停用插件功能 - /// - void Disable(); - - /// - /// 获取插件设置界面 - /// 此方法返回插件的设置界面控件,用于展示在设置窗口 - /// - /// 插件设置界面 - UserControl GetSettingsView(); - - /// - /// 插件卸载时的清理工作 - /// 此方法在插件被卸载前调用,用于释放资源和执行清理 - /// - void Cleanup(); - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IPluginService.cs b/Ink Canvas/Helpers/Plugins/IPluginService.cs deleted file mode 100644 index 9559a992..00000000 --- a/Ink Canvas/Helpers/Plugins/IPluginService.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 插件服务接口,提供对软件内部功能的访问 - /// 继承自三个专门的服务接口:获取服务、窗口服务、操作服务 - /// - public interface IPluginService : IGetService, IWindowService, IActionService - { - // 这个接口现在继承自三个专门的服务接口 - // 所有方法都在子接口中定义,这里不需要重复定义 - } - - /// - /// 通知类型枚举 - /// - public enum NotificationType - { - /// - /// 信息 - /// - Info, - - /// - /// 成功 - /// - Success, - - /// - /// 警告 - /// - Warning, - - /// - /// 错误 - /// - Error - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/IWindowService.cs b/Ink Canvas/Helpers/Plugins/IWindowService.cs deleted file mode 100644 index eb6fb863..00000000 --- a/Ink Canvas/Helpers/Plugins/IWindowService.cs +++ /dev/null @@ -1,152 +0,0 @@ -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 窗口服务接口,统一所有窗口操作相关的方法 - /// - public interface IWindowService - { - #region 窗口显示和隐藏 - - /// - /// 显示设置窗口 - /// - void ShowSettingsWindow(); - - /// - /// 隐藏设置窗口 - /// - void HideSettingsWindow(); - - /// - /// 显示插件设置窗口 - /// - void ShowPluginSettingsWindow(); - - /// - /// 隐藏插件设置窗口 - /// - void HidePluginSettingsWindow(); - - /// - /// 显示帮助窗口 - /// - void ShowHelpWindow(); - - /// - /// 隐藏帮助窗口 - /// - void HideHelpWindow(); - - /// - /// 显示关于窗口 - /// - void ShowAboutWindow(); - - /// - /// 隐藏关于窗口 - /// - void HideAboutWindow(); - - #endregion - - #region 对话框和通知 - - /// - /// 显示通知消息 - /// - /// 消息内容 - /// 消息类型 - void ShowNotification(string message, NotificationType type = NotificationType.Info); - - /// - /// 显示确认对话框 - /// - /// 消息内容 - /// 标题 - /// 用户选择结果 - bool ShowConfirmDialog(string message, string title = "确认"); - - /// - /// 显示输入对话框 - /// - /// 提示消息 - /// 标题 - /// 默认值 - /// 用户输入内容 - string ShowInputDialog(string message, string title = "输入", string defaultValue = ""); - - #endregion - - #region 窗口状态控制 - - /// - /// 设置窗口全屏状态 - /// - /// 是否全屏 - void SetFullScreen(bool isFullScreen); - - /// - /// 设置窗口置顶状态 - /// - /// 是否置顶 - void SetTopMost(bool isTopMost); - - /// - /// 设置窗口可见性 - /// - /// 是否可见 - void SetWindowVisibility(bool isVisible); - - /// - /// 最小化窗口 - /// - void MinimizeWindow(); - - /// - /// 最大化窗口 - /// - void MaximizeWindow(); - - /// - /// 恢复窗口 - /// - void RestoreWindow(); - - /// - /// 关闭窗口 - /// - void CloseWindow(); - - #endregion - - #region 窗口位置和大小 - - /// - /// 设置窗口位置 - /// - /// X坐标 - /// Y坐标 - void SetWindowPosition(double x, double y); - - /// - /// 设置窗口大小 - /// - /// 宽度 - /// 高度 - void SetWindowSize(double width, double height); - - /// - /// 获取窗口位置 - /// - /// 窗口位置 - (double x, double y) GetWindowPosition(); - - /// - /// 获取窗口大小 - /// - /// 窗口大小 - (double width, double height) GetWindowSize(); - - #endregion - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/PluginBase.cs b/Ink Canvas/Helpers/Plugins/PluginBase.cs deleted file mode 100644 index 0c960100..00000000 --- a/Ink Canvas/Helpers/Plugins/PluginBase.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Windows.Controls; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 插件基类,提供基本实现 - /// - public abstract class PluginBase : IPlugin - { - /// - /// 插件状态(私有字段) - /// - private bool _isEnabled; - - /// - /// 插件状态(公共属性) - /// - public bool IsEnabled - { - get => _isEnabled; - protected set - { - if (_isEnabled != value) - { - _isEnabled = value; - OnEnabledStateChanged(value); - } - } - } - - /// - /// 插件ID - /// - public string Id { get; protected set; } - - /// - /// 写入 配置时使用的稳定键(默认同类型全名;多实例类型如 SDK 目录插件应重写)。 - /// - public virtual string PluginStateKey => GetType().FullName; - - /// - /// 插件路径 - /// - public string PluginPath { get; set; } - - /// - /// 插件名称 - /// - public abstract string Name { get; } - - /// - /// 插件描述 - /// - public abstract string Description { get; } - - /// - /// 插件版本 - /// - public abstract Version Version { get; } - - /// - /// 插件作者 - /// - public abstract string Author { get; } - - /// - /// 是否为内置插件 - /// - public virtual bool IsBuiltIn => false; - - /// - /// 状态变更事件 - /// - public event EventHandler EnabledStateChanged; - - /// - /// 初始化插件 - /// - public virtual void Initialize() - { - Id = GetType().FullName; - - // 添加日志,记录插件名称 - try - { - string name = Name; - LogHelper.WriteLogToFile($"初始化插件: ID={Id}, 名称={name ?? "未命名"}"); - - if (string.IsNullOrEmpty(name)) - { - LogHelper.WriteLogToFile($"警告: 插件 {Id} 的名称为空", LogHelper.LogType.Warning); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"获取插件名称时出错: {ex.Message}", LogHelper.LogType.Error); - } - - LogHelper.WriteLogToFile($"插件 {Name} 已初始化"); - } - - /// - /// 启用插件 - /// - public virtual void Enable() - { - if (!IsEnabled) - { - IsEnabled = true; - LogHelper.WriteLogToFile($"插件 {Name} 已启用"); - } - } - - /// - /// 禁用插件 - /// - public virtual void Disable() - { - if (IsEnabled) - { - IsEnabled = false; - LogHelper.WriteLogToFile($"插件 {Name} 已禁用"); - } - } - - /// - /// 获取插件设置界面 - /// - /// 插件设置界面 - public virtual UserControl GetSettingsView() - { - // 默认返回空设置页面 - return new UserControl(); - } - - /// - /// 插件卸载时的清理工作 - /// - public virtual void Cleanup() - { - LogHelper.WriteLogToFile($"插件 {Name} 已卸载"); - } - - /// - /// 保存插件自身的设置 - /// 注意:此方法仅用于保存插件的特定设置,不应影响插件启用/禁用状态 - /// 插件启用状态由PluginManager统一管理 - /// - public virtual void SavePluginSettings() - { - // 默认实现不做任何事情 - // 子类可以重写此方法,将自身设置保存到配置文件中 - LogHelper.WriteLogToFile($"插件 {Name} 设置已保存", LogHelper.LogType.Event); - } - - /// - /// 触发状态变更事件 - /// - /// 是否启用 - protected virtual void OnEnabledStateChanged(bool isEnabled) - { - EnabledStateChanged?.Invoke(this, isEnabled); - } - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/PluginManager.cs b/Ink Canvas/Helpers/Plugins/PluginManager.cs deleted file mode 100644 index 82c4c7d0..00000000 --- a/Ink Canvas/Helpers/Plugins/PluginManager.cs +++ /dev/null @@ -1,1622 +0,0 @@ -using Ink_Canvas.Windows; -using InkCanvasForClass.PluginHost; -using InkCanvasForClass.PluginSdk; -using Newtonsoft.Json; -using System; -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Security.Cryptography; -using System.Threading; -using System.Threading.Tasks; -using System.Windows; -using Timer = System.Timers.Timer; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 插件管理器,负责插件的加载、卸载和管理 - /// - public class PluginManager - { - private static readonly string PluginsDirectory = Path.Combine(App.RootPath, "Plugins"); - private static readonly string PluginConfigFile = Path.Combine(App.RootPath, "Configs", "PluginConfig.json"); - private static readonly string PluginConfigBackupFile = Path.Combine(App.RootPath, "Configs", "PluginConfig.json.bak"); - - private static PluginManager _instance; - private static SemaphoreSlim _configLock = new SemaphoreSlim(1, 1); - - /// - /// 插件管理器单例 - /// - public static PluginManager Instance - { - get - { - if (_instance == null) - { - _instance = new PluginManager(); - } - return _instance; - } - } - - /// - /// 已加载的插件集合 - /// - public ObservableCollection Plugins { get; } = new ObservableCollection(); - - /// - /// 插件配置信息 - /// - public Dictionary PluginStates { get; private set; } = new Dictionary(); - - /// - /// 配置是否已更改但未保存 - /// - private bool _configDirty; - - /// - /// 配置自动保存计时器 - /// - private Timer _autoSaveTimer; - - /// - /// 加载的程序集缓存 - /// - private Dictionary _loadedAssemblies = new Dictionary(); - - /// - /// 插件文件哈希缓存,用于热重载检测 - /// - private Dictionary _pluginHashes = new Dictionary(); - - /// - /// SDK 插件程序集(按主 DLL 路径缓存) - /// - private readonly Dictionary _sdkAssembliesByPath = - new Dictionary(StringComparer.OrdinalIgnoreCase); - - /// - /// 已加载的 SDK 插件核心实例(键为插件目录名) - /// - private readonly Dictionary _sdkCoreByFolderId = - new Dictionary(StringComparer.OrdinalIgnoreCase); - - /// - /// SDK 插件登记的菜单 / 工具栏 / 设置页,供主窗口挂载。 - /// - public CollectingPluginRegistry ExtensionRegistry { get; } = new CollectingPluginRegistry(); - - private PluginManager() - { - // 确保插件目录存在 - if (!Directory.Exists(PluginsDirectory)) - { - Directory.CreateDirectory(PluginsDirectory); - } - - - // 初始化自动保存计时器(3秒) - _autoSaveTimer = new Timer(3000); - _autoSaveTimer.Elapsed += (s, e) => - { - if (_configDirty) - { - SaveConfigAsync().ConfigureAwait(false); - } - }; - _autoSaveTimer.AutoReset = false; - - // 注册插件状态变更事件处理 - AppDomain.CurrentDomain.ProcessExit += (s, e) => - { - // 应用退出时强制保存配置 - if (_configDirty) - { - SaveConfig(); - } - }; - } - - private static string GetPluginStateKey(IPlugin plugin) - { - if (plugin is PluginBase pluginBase) - { - return pluginBase.PluginStateKey; - } - - return plugin.GetType().FullName; - } - - public IInkCanvasPlugin GetSdkPluginInstance(string folderId) - { - if (string.IsNullOrEmpty(folderId)) - { - return null; - } - - return _sdkCoreByFolderId.TryGetValue(folderId, out var core) ? core : null; - } - - public IReadOnlyList GetAllSdkPluginInstances() - { - return _sdkCoreByFolderId.Values.ToList(); - } - - public IInkCanvasPlugin GetSdkPluginByName(string name) - { - return _sdkCoreByFolderId.Values.FirstOrDefault(p => p.Name == name); - } - - public void SetSdkPluginEnabledByName(string name, bool enable) - { - var adapter = Plugins.OfType().FirstOrDefault(a => - a.Name == name || string.Equals(a.FolderId, name, StringComparison.OrdinalIgnoreCase)); - if (adapter == null) - { - return; - } - - TogglePlugin(adapter, enable); - } - - public void UnloadSdkPluginByName(string name) - { - var adapter = Plugins.OfType().FirstOrDefault(a => - a.Name == name || string.Equals(a.FolderId, name, StringComparison.OrdinalIgnoreCase)); - if (adapter == null) - { - return; - } - - UnloadPlugin(adapter, true); - } - - /// - /// 初始化插件系统 - /// - public void Initialize() - { - try - { - LogHelper.WriteLogToFile("开始初始化插件系统"); - - // 加载配置 - LoadConfig(); - LogHelper.WriteLogToFile($"已从配置文件加载 {PluginStates.Count} 个插件状态记录"); - - // 加载内置插件 - LogHelper.WriteLogToFile("正在加载内置插件..."); - LoadBuiltInPlugins(); - - // 加载外部插件 - LogHelper.WriteLogToFile("正在加载外部插件..."); - LoadExternalPlugins(); - - // 加载 Plugins 子目录中的 SDK 插件(IInkCanvasPlugin) - LogHelper.WriteLogToFile("正在加载 SDK 插件(子目录)..."); - LoadSdkPluginsFromSubfolders(); - - // 启用已配置为启用的插件 - LogHelper.WriteLogToFile("正在应用配置的插件状态..."); - EnableConfiguredPlugins(); - - // 设置定期检查热重载 - StartHotReloadWatcher(); - - // 保存初始化后的配置(可能有新插件) - SaveConfig(); - - LogHelper.WriteLogToFile($"插件系统初始化完成,共加载 {Plugins.Count} 个插件"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"初始化插件系统时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 加载内置插件 - /// - private void LoadBuiltInPlugins() - { - try - { - // 获取当前程序集 - Assembly currentAssembly = Assembly.GetExecutingAssembly(); - - // 查找实现了IPlugin接口的所有类型 - var pluginTypes = currentAssembly.GetTypes() - .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass); - - foreach (var pluginType in pluginTypes) - { - try - { - // 创建插件实例 - IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); - - // 只处理内置插件 - if (plugin.IsBuiltIn) - { - plugin.Initialize(); - Plugins.Add(plugin); - LogHelper.WriteLogToFile($"已加载内置插件: {plugin.Name} v{plugin.Version}"); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载内置插件 {pluginType.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载内置插件时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 加载外部插件 - /// - private void LoadExternalPlugins() - { - try - { - // 检查插件目录是否存在 - if (!Directory.Exists(PluginsDirectory)) - { - Directory.CreateDirectory(PluginsDirectory); - return; - } - - // 获取所有插件文件(支持 .iccpp 和 .dll 格式) - var pluginFiles = Directory.GetFiles(PluginsDirectory, "*.iccpp", SearchOption.TopDirectoryOnly) - .Concat(Directory.GetFiles(PluginsDirectory, "*.dll", SearchOption.TopDirectoryOnly)) - .ToArray(); - - LogHelper.WriteLogToFile($"发现 {pluginFiles.Length} 个外部插件文件"); - - foreach (var pluginFile in pluginFiles) - { - LoadExternalPlugin(pluginFile); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载外部插件时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 扫描 下一层子目录,加载实现 的 SDK 插件。 - /// - private void LoadSdkPluginsFromSubfolders() - { - try - { - if (!Directory.Exists(PluginsDirectory)) - { - return; - } - - foreach (var pluginDir in Directory.GetDirectories(PluginsDirectory)) - { - var folderId = Path.GetFileName(pluginDir.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar)); - if (string.IsNullOrEmpty(folderId)) - { - continue; - } - - var dllFiles = Directory.GetFiles(pluginDir, "*.dll", SearchOption.AllDirectories); - var mainDll = dllFiles.FirstOrDefault(f => - f.IndexOf($"{Path.DirectorySeparatorChar}lib{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0 && - f.IndexOf($"{Path.AltDirectorySeparatorChar}lib{Path.AltDirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0 && - f.IndexOf($"{Path.DirectorySeparatorChar}runtimes{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0 && - f.IndexOf($"{Path.AltDirectorySeparatorChar}runtimes{Path.AltDirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) < 0); - - if (mainDll == null) - { - continue; - } - - try - { - if (!_sdkAssembliesByPath.TryGetValue(mainDll, out var assembly)) - { - assembly = Assembly.LoadFrom(mainDll); - _sdkAssembliesByPath[mainDll] = assembly; - } - - Type pluginType = null; - try - { - pluginType = assembly.GetTypes() - .FirstOrDefault(t => - typeof(IInkCanvasPlugin).IsAssignableFrom(t) && - !t.IsAbstract && - !t.IsInterface && - t.IsClass); - } - catch (ReflectionTypeLoadException ex) - { - LogHelper.WriteLogToFile($"枚举 SDK 插件类型失败 {folderId}: {ex.Message}", LogHelper.LogType.Error); - } - - if (pluginType == null) - { - continue; - } - - var core = (IInkCanvasPlugin)Activator.CreateInstance(pluginType); - _sdkCoreByFolderId[folderId] = core; - - var adapter = new SdkPluginAdapter(folderId, core, mainDll); - adapter.Initialize(); - Plugins.Add(adapter); - - LogHelper.WriteLogToFile($"已加载 SDK 插件(子目录): {core.Name} — {folderId}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载 SDK 插件目录 {folderId} 失败: {ex.Message}", LogHelper.LogType.Error); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"扫描 SDK 插件子目录失败: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 加载单个外部插件 - /// - /// 插件文件路径 - /// 加载的插件实例,加载失败则返回null - public IPlugin LoadExternalPlugin(string pluginPath) - { - try - { - // 计算文件哈希 - string fileHash = CalculateFileHash(pluginPath); - _pluginHashes[pluginPath] = fileHash; - - // 检查文件扩展名 - string extension = Path.GetExtension(pluginPath).ToLowerInvariant(); - if (extension == ".iccpp") - { - // 创建 ICCPP 插件适配器 - return CreateICCPPPluginAdapter(pluginPath); - } - - // 加载插件程序集 - Assembly pluginAssembly = LoadPluginAssembly(pluginPath); - if (pluginAssembly == null) return null; - - // 查找实现了IPlugin接口的类型 - var pluginTypes = pluginAssembly.GetTypes() - .Where(t => typeof(IPlugin).IsAssignableFrom(t) && !t.IsAbstract && t.IsClass); - - foreach (var pluginType in pluginTypes) - { - try - { - // 创建插件实例 - IPlugin plugin = (IPlugin)Activator.CreateInstance(pluginType); - - // 设置插件路径 - if (plugin is PluginBase pluginBase) - { - pluginBase.PluginPath = pluginPath; - } - - plugin.Initialize(); - Plugins.Add(plugin); - - LogHelper.WriteLogToFile($"已加载外部插件: {plugin.Name} v{plugin.Version} 来自 {Path.GetFileName(pluginPath)}"); - - return plugin; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"实例化插件类型 {pluginType.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - LogHelper.WriteLogToFile($"在程序集 {Path.GetFileName(pluginPath)} 中未找到有效的插件类型", LogHelper.LogType.Warning); - return null; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载外部插件 {Path.GetFileName(pluginPath)} 时出错: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 创建 ICCPP 插件适配器 - /// - /// 插件文件路径 - /// 适配的插件实例 - private IPlugin CreateICCPPPluginAdapter(string pluginPath) - { - try - { - // 读取插件文件内容 - byte[] pluginData = File.ReadAllBytes(pluginPath); - - // 创建适配器插件实例 - var pluginAdapter = new ICCPPPluginAdapter(pluginPath, pluginData); - - // 添加到插件列表 - Plugins.Add(pluginAdapter); - - LogHelper.WriteLogToFile($"已创建 ICCPP 插件适配器: {pluginAdapter.Name} 来自 {Path.GetFileName(pluginPath)}"); - - return pluginAdapter; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"创建 ICCPP 插件适配器时出错: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 加载插件程序集 - /// - /// 插件文件路径 - /// 加载的程序集 - private Assembly LoadPluginAssembly(string pluginPath) - { - try - { - // 检查是否已加载该程序集 - if (_loadedAssemblies.TryGetValue(pluginPath, out var loadedAssembly)) - { - return loadedAssembly; - } - - // 直接加载程序集 - Assembly pluginAssembly = Assembly.LoadFrom(pluginPath); - _loadedAssemblies[pluginPath] = pluginAssembly; - - return pluginAssembly; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载插件程序集 {Path.GetFileName(pluginPath)} 时出错: {ex.Message}", LogHelper.LogType.Error); - return null; - } - } - - /// - /// 启用已配置为启用的插件 - /// - private void EnableConfiguredPlugins() - { - int enabledCount = 0; - int disabledCount = 0; - int errorCount = 0; - - foreach (var plugin in Plugins) - { - try - { - string pluginTypeName = GetPluginStateKey(plugin); - - // 检查配置中的插件状态 - if (PluginStates.TryGetValue(pluginTypeName, out bool enabled)) - { - // 获取当前实际状态 - bool currentState = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - - // 如果配置状态与当前状态不一致,则应用配置状态 - if (currentState != enabled) - { - // 注册插件状态变更事件 - if (plugin is PluginBase pb) - { - pb.EnabledStateChanged += Plugin_EnabledStateChanged; - } - - if (enabled) - { - plugin.Enable(); - enabledCount++; - LogHelper.WriteLogToFile($"根据配置启用插件: {plugin.Name}"); - } - else - { - plugin.Disable(); - disabledCount++; - LogHelper.WriteLogToFile($"根据配置禁用插件: {plugin.Name}"); - } - } - else - { - // 状态一致,只注册事件 - if (plugin is PluginBase pb) - { - pb.EnabledStateChanged += Plugin_EnabledStateChanged; - } - } - } - else - { - // 插件不在配置中,添加默认状态(禁用) - PluginStates[pluginTypeName] = false; - _configDirty = true; - - // 注册插件状态变更事件 - if (plugin is PluginBase pb) - { - pb.EnabledStateChanged += Plugin_EnabledStateChanged; - } - - // 如果当前是启用状态,则禁用 - if (plugin is PluginBase pluginBase && pluginBase.IsEnabled) - { - plugin.Disable(); - disabledCount++; - LogHelper.WriteLogToFile($"插件不在配置中,默认禁用: {plugin.Name}"); - } - } - } - catch (Exception ex) - { - errorCount++; - LogHelper.WriteLogToFile($"应用插件 {plugin.Name} 配置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - // 如果有配置变更,启动自动保存 - if (_configDirty) - { - TriggerAutoSave(); - } - - LogHelper.WriteLogToFile($"已应用插件配置: 启用 {enabledCount} 个,禁用 {disabledCount} 个,错误 {errorCount} 个"); - } - - /// - /// 插件状态变更事件处理 - /// - private void Plugin_EnabledStateChanged(object sender, bool isEnabled) - { - try - { - if (sender is IPlugin plugin) - { - string pluginTypeName = GetPluginStateKey(plugin); - - // 更新配置状态 - if (!PluginStates.ContainsKey(pluginTypeName) || PluginStates[pluginTypeName] != isEnabled) - { - PluginStates[pluginTypeName] = isEnabled; - _configDirty = true; - - LogHelper.WriteLogToFile($"插件状态变更: {plugin.Name} = {(isEnabled ? "启用" : "禁用")}"); - - // 立即同步保存配置(不再使用延迟自动保存) - SaveConfig(); - LogHelper.WriteLogToFile($"插件 {plugin.Name} 状态已立即保存到配置文件"); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"处理插件状态变更事件时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 触发自动保存计时器 - /// - private void TriggerAutoSave() - { - // 重置并启动计时器 - _autoSaveTimer.Stop(); - _autoSaveTimer.Start(); - } - - /// - /// 启动热重载监视器 - /// - private void StartHotReloadWatcher() - { - // 创建定时检查任务 - Task.Run(async () => - { - while (true) - { - try - { - // 每5秒检查一次 - await Task.Delay(5000); - - // 获取所有外部插件 - var externalPlugins = Plugins.OfType() - .Where(p => !p.IsBuiltIn && !string.IsNullOrEmpty(p.PluginPath)) - .ToList(); - - foreach (var plugin in externalPlugins) - { - // 检查插件文件是否存在 - if (!File.Exists(plugin.PluginPath)) - { - continue; - } - - // 计算当前文件哈希 - string currentHash = CalculateFileHash(plugin.PluginPath); - - // 比较哈希值是否变化 - if (_pluginHashes.TryGetValue(plugin.PluginPath, out string oldHash) && - !string.IsNullOrEmpty(oldHash) && - oldHash != currentHash) - { - // 文件已变化,执行热重载 - Application.Current.Dispatcher.Invoke(() => - { - ReloadPlugin(plugin); - }); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"热重载检查出错: {ex.Message}", LogHelper.LogType.Error); - } - } - }); - } - - /// - /// 重新加载插件 - /// - /// 要重新加载的插件 - private void ReloadPlugin(PluginBase plugin) - { - try - { - string pluginPath = plugin.PluginPath; - if (string.IsNullOrEmpty(pluginPath) || !File.Exists(pluginPath)) - { - LogHelper.WriteLogToFile($"无法重新加载插件 {plugin.Name}: 插件文件不存在", LogHelper.LogType.Error); - return; - } - - LogHelper.WriteLogToFile($"开始热重载插件: {plugin.Name} ({Path.GetFileName(pluginPath)})"); - - // 保存插件的当前状态 - bool wasEnabled = plugin.IsEnabled; - string pluginTypeName = GetPluginStateKey(plugin); - - // 卸载插件 - UnloadPlugin(plugin); - - // 从加载缓存中移除 - if (_loadedAssemblies.ContainsKey(pluginPath)) - { - _loadedAssemblies.Remove(pluginPath); - } - - // 计算新的文件哈希 - string newHash = CalculateFileHash(pluginPath); - _pluginHashes[pluginPath] = newHash; - - // 重新加载插件 - IPlugin newPlugin = LoadExternalPlugin(pluginPath); - - if (newPlugin != null) - { - // 恢复插件状态 - if (wasEnabled) - { - newPlugin.Enable(); - } - - // 更新配置(如果类型名称变化) - string newPluginTypeName = GetPluginStateKey(newPlugin); - if (pluginTypeName != newPluginTypeName && PluginStates.ContainsKey(pluginTypeName)) - { - bool state = PluginStates[pluginTypeName]; - PluginStates.Remove(pluginTypeName); - PluginStates[newPluginTypeName] = state; - _configDirty = true; - SaveConfig(); - } - - LogHelper.WriteLogToFile($"插件 {newPlugin.Name} v{newPlugin.Version} 热重载成功"); - - // 通知UI刷新 - NotifyUIRefresh(); - } - else - { - LogHelper.WriteLogToFile($"插件 {plugin.Name} 热重载失败", LogHelper.LogType.Error); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重新加载插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 卸载插件 - /// - /// 要卸载的插件 - /// 是否从配置中移除 - public void UnloadPlugin(IPlugin plugin, bool removeFromConfig = false) - { - try - { - // 保存插件名称,以便在卸载后使用 - string pluginName = plugin.Name; - - // 如果插件已启用,先禁用它 - if (plugin is PluginBase pluginBase && pluginBase.IsEnabled) - { - plugin.Disable(); - } - - // 执行插件清理 - plugin.Cleanup(); - - // 从插件集合中移除 - Plugins.Remove(plugin); - - if (plugin is SdkPluginAdapter sdkAdapter) - { - _sdkCoreByFolderId.Remove(sdkAdapter.FolderId); - } - - // 从配置中移除(如果需要) - if (removeFromConfig && plugin.GetType() != null) - { - string pluginTypeName = GetPluginStateKey(plugin); - if (PluginStates.ContainsKey(pluginTypeName)) - { - PluginStates.Remove(pluginTypeName); - SaveConfig(); - } - } - - LogHelper.WriteLogToFile($"已卸载插件: {pluginName}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"卸载插件时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 删除插件 - /// - /// 要删除的插件 - /// 删除是否成功 - public bool DeletePlugin(IPlugin plugin) - { - try - { - // 只能删除外部插件 - if (plugin.IsBuiltIn) - { - return false; - } - - // 保存插件名称,以便在删除后使用 - string pluginName = plugin.Name; - - // 获取插件路径 - string pluginPath = null; - if (plugin is PluginBase pluginBase) - { - pluginPath = pluginBase.PluginPath; - } - - if (string.IsNullOrEmpty(pluginPath) || !File.Exists(pluginPath)) - { - return false; - } - - // 卸载插件(并从配置中移除状态) - UnloadPlugin(plugin, true); - - // 删除插件文件 - File.Delete(pluginPath); - - // 清理缓存 - _loadedAssemblies.Remove(pluginPath); - _pluginHashes.Remove(pluginPath); - - // 保存配置 - SaveConfig(); - - LogHelper.WriteLogToFile($"已删除插件: {pluginName}"); - return true; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"删除插件时出错: {ex.Message}", LogHelper.LogType.Error); - return false; - } - } - - /// - /// 切换插件启用状态 - /// - /// 目标插件 - /// 是否启用 - public void TogglePlugin(IPlugin plugin, bool enable) - { - try - { - // 检查当前状态是否已经是目标状态 - bool currentState = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - if (currentState == enable) - { - // 已经是目标状态,无需操作 - LogHelper.WriteLogToFile($"插件 {plugin.Name} 已经是 {(enable ? "启用" : "禁用")} 状态,无需切换"); - return; - } - - // 记录插件信息,用于日志 - string pluginName = plugin.Name; - string pluginTypeName = GetPluginStateKey(plugin); - - LogHelper.WriteLogToFile($"开始切换插件 {pluginName} 状态为: {(enable ? "启用" : "禁用")}"); - - // 首先更新配置状态 - PluginStates[pluginTypeName] = enable; - _configDirty = true; - - // 更新插件状态 - try - { - // 注册事件(无需检查事件是否为null) - if (plugin is PluginBase pb) - { - // 先取消可能已有的订阅,避免重复订阅 - pb.EnabledStateChanged -= Plugin_EnabledStateChanged; - // 重新订阅 - pb.EnabledStateChanged += Plugin_EnabledStateChanged; - } - - // 更新插件状态 - if (enable) - { - plugin.Enable(); - LogHelper.WriteLogToFile($"插件 {pluginName} 已启用"); - } - else - { - // 禁用前先记录是否为内置插件 - bool isBuiltIn = plugin.IsBuiltIn; - LogHelper.WriteLogToFile($"尝试禁用{(isBuiltIn ? "内置" : "外部")}插件 {pluginName}"); - - // 禁用插件 - plugin.Disable(); - - // 禁用后立即检查状态,确保禁用成功 - bool actuallyDisabled = !(plugin is PluginBase pb2 && pb2.IsEnabled); - if (!actuallyDisabled) - { - LogHelper.WriteLogToFile($"警告: 插件 {pluginName} 禁用失败,再次尝试禁用", LogHelper.LogType.Warning); - plugin.Disable(); // 再次尝试禁用 - - // 再次检查 - actuallyDisabled = !(plugin is PluginBase pb3 && pb3.IsEnabled); - if (!actuallyDisabled) - { - LogHelper.WriteLogToFile($"错误: 插件 {pluginName} 禁用失败,强制设置禁用状态", LogHelper.LogType.Error); - // 强制设置状态 - if (plugin is PluginBase pb4) - { - // 使用反射强制设置禁用状态 - var enabledProperty = typeof(PluginBase).GetProperty("IsEnabled"); - if (enabledProperty != null) - { - enabledProperty.SetValue(pb4, false); - LogHelper.WriteLogToFile($"已通过反射强制设置插件 {pluginName} 为禁用状态"); - } - } - } - } - - LogHelper.WriteLogToFile($"插件 {pluginName} 已禁用"); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"更改插件 {pluginName} 状态时出错: {ex.Message}", LogHelper.LogType.Error); - } - - // 立即保存配置 - SaveConfigAsync().ConfigureAwait(false); - - // 插件状态切换后,始终进行重载(无论是启用还是禁用) - if (plugin is PluginBase pluginInstance) - { - // 对于内置插件,执行专门的处理 - if (pluginInstance.IsBuiltIn) - { - LogHelper.WriteLogToFile($"处理内置插件 {pluginName} 状态变更"); - - // 对于内置插件,我们需要确保状态正确应用 - bool finalState = pluginInstance.IsEnabled; - bool expectedState = enable; - - if (finalState != expectedState) - { - LogHelper.WriteLogToFile($"内置插件状态不匹配: 当前={finalState}, 期望={expectedState},尝试纠正", LogHelper.LogType.Warning); - - // 再次尝试设置状态 - if (expectedState) - { - plugin.Enable(); - } - else - { - plugin.Disable(); - - // 最后一次检查,如果仍然不匹配,强制设置 - if (pluginInstance.IsEnabled != expectedState) - { - var enabledProperty = typeof(PluginBase).GetProperty("IsEnabled"); - if (enabledProperty != null) - { - enabledProperty.SetValue(pluginInstance, expectedState); - LogHelper.WriteLogToFile($"已通过反射强制设置内置插件 {pluginName} 状态为 {(expectedState ? "启用" : "禁用")}"); - } - } - } - } - - // 通知UI刷新 - NotifyUIRefresh(); - } - else - { - // 外部插件,执行热重载 - try - { - if (!string.IsNullOrEmpty(pluginInstance.PluginPath) && File.Exists(pluginInstance.PluginPath)) - { - LogHelper.WriteLogToFile($"开始重载外部插件 {pluginName}"); - - // 使用调度器确保在UI线程执行热重载 - if (Application.Current != null && Application.Current.Dispatcher != null) - { - Application.Current.Dispatcher.BeginInvoke(new Action(() => - { - ReloadPlugin(pluginInstance); - LogHelper.WriteLogToFile($"插件 {pluginName} 已重载以应用{(enable ? "启用" : "禁用")}状态"); - })); - } - else - { - // 当前不在UI线程,直接重载 - ReloadPlugin(pluginInstance); - LogHelper.WriteLogToFile($"插件 {pluginName} 已重载以应用{(enable ? "启用" : "禁用")}状态"); - } - } - else - { - LogHelper.WriteLogToFile($"外部插件 {pluginName} 文件不存在,无法重载", LogHelper.LogType.Warning); - NotifyUIRefresh(); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重载插件 {pluginName} 时出错: {ex.Message}", LogHelper.LogType.Error); - // 出错时也要刷新UI - NotifyUIRefresh(); - } - } - } - else - { - // 通知UI刷新 - NotifyUIRefresh(); - } - - LogHelper.WriteLogToFile($"插件 {pluginName} 状态切换完成"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"切换插件状态时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 应用插件实时状态 - /// - /// 目标插件 - /// 是否启用 - private void ApplyPluginRealTimeState(IPlugin plugin, bool enable) - { - try - { - // 确保当前实例状态正确 - bool currentState = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - if (currentState != enable) - { - if (enable) - { - plugin.Enable(); - LogHelper.WriteLogToFile($"实时应用: 已启用插件 {plugin.Name}"); - } - else - { - plugin.Disable(); - LogHelper.WriteLogToFile($"实时应用: 已禁用插件 {plugin.Name}"); - } - - // 同步状态到插件自身的配置 - if (plugin is PluginBase pluginSettings) - { - try - { - // 保存插件设置(与启用状态无关) - pluginSettings.SavePluginSettings(); - LogHelper.WriteLogToFile($"实时应用: 已保存插件 {plugin.Name} 设置"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"实时应用: 保存插件 {plugin.Name} 设置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - } - - // 对于外部插件,尝试执行热重载以确保状态立即生效 - if (plugin is PluginBase externalPlugin && !externalPlugin.IsBuiltIn) - { - string pluginPath = externalPlugin.PluginPath; - if (!string.IsNullOrEmpty(pluginPath) && File.Exists(pluginPath)) - { - // 记录插件类型名称,用于后续状态检查 - string pluginTypeName = GetPluginStateKey(plugin); - bool targetState = enable; - - // 使用调度器确保在UI线程执行热重载 - if (Application.Current != null && Application.Current.Dispatcher != null) - { - Application.Current.Dispatcher.BeginInvoke(new Action(() => - { - try - { - // 热重载前再次确认配置状态正确 - if (PluginStates.TryGetValue(pluginTypeName, out bool storedStateUi) && storedStateUi != targetState) - { - LogHelper.WriteLogToFile($"热重载前发现状态不一致,修正配置: {plugin.Name}, 配置={storedStateUi}, 目标={targetState}", LogHelper.LogType.Warning); - PluginStates[pluginTypeName] = targetState; - SaveConfig(); - } - - // 执行热重载 - ReloadPlugin(externalPlugin); - LogHelper.WriteLogToFile($"插件 {plugin.Name} 已成功热重载以应用实时状态"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"热重载插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - })); - } - else - { - // 当前不在UI线程,直接重载 - // 热重载前再次确认配置状态正确 - if (PluginStates.TryGetValue(pluginTypeName, out bool storedStateNonUi) && storedStateNonUi != targetState) - { - LogHelper.WriteLogToFile($"热重载前发现状态不一致,修正配置: {plugin.Name}, 配置={storedStateNonUi}, 目标={targetState}", LogHelper.LogType.Warning); - PluginStates[pluginTypeName] = targetState; - SaveConfig(); - } - - ReloadPlugin(externalPlugin); - } - } - } - - LogHelper.WriteLogToFile($"插件 {plugin.Name} 实时状态已应用: {(enable ? "启用" : "禁用")}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"应用插件实时状态时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 通知UI刷新 - /// - private void NotifyUIRefresh() - { - try - { - // 通知UI刷新 - if (Application.Current != null && Application.Current.Dispatcher != null) - { - Application.Current.Dispatcher.BeginInvoke(new Action(() => - { - // 通知任何可能打开的插件设置窗口刷新 - foreach (Window window in Application.Current.Windows) - { - if (window is PluginSettingsWindow pluginWindow) - { - pluginWindow.RefreshPluginList(); - break; - } - } - })); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"通知UI刷新时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 加载插件配置 - /// - private void LoadConfig() - { - const int maxRetries = 3; // 最大重试次数 - const int retryDelayMs = 300; // 重试延迟时间(毫秒) - - LogHelper.WriteLogToFile($"开始从配置文件加载插件状态: {PluginConfigFile}"); - - // 确保至少有一个默认配置 - Dictionary defaultConfig = new Dictionary(); - - // 尝试获取配置锁 - _configLock.Wait(); - - try - { - for (int attempt = 1; attempt <= maxRetries; attempt++) - { - try - { - if (File.Exists(PluginConfigFile)) - { - string json; - // 使用共享读取模式,允许其他进程同时读取但不允许写入 - using (FileStream fs = new FileStream(PluginConfigFile, FileMode.Open, FileAccess.Read, FileShare.Read)) - using (StreamReader reader = new StreamReader(fs)) - { - json = reader.ReadToEnd(); - } - - var loadedStates = JsonConvert.DeserializeObject>(json); - - if (loadedStates != null && loadedStates.Count > 0) - { - PluginStates = loadedStates; - _configDirty = false; // 重置脏标记 - LogHelper.WriteLogToFile($"成功从配置文件加载了 {PluginStates.Count} 个插件状态"); - } - else - { - LogHelper.WriteLogToFile("配置文件解析为空,尝试使用备份", LogHelper.LogType.Warning); - // 尝试加载备份 - if (File.Exists(PluginConfigBackupFile)) - { - try - { - string backupJson = File.ReadAllText(PluginConfigBackupFile); - var backupStates = JsonConvert.DeserializeObject>(backupJson); - - if (backupStates != null && backupStates.Count > 0) - { - PluginStates = backupStates; - _configDirty = true; // 从备份加载,需要重新保存主配置 - LogHelper.WriteLogToFile($"已从备份恢复 {PluginStates.Count} 个插件状态"); - return; // 成功从备份加载,提前退出 - } - } - catch (Exception backupEx) - { - LogHelper.WriteLogToFile($"从备份恢复配置失败: {backupEx.Message}", LogHelper.LogType.Error); - } - } - - // 备份也失败,使用默认配置 - PluginStates = defaultConfig; - _configDirty = true; - } - } - else - { - LogHelper.WriteLogToFile($"配置文件不存在,尝试使用备份: {PluginConfigFile}", LogHelper.LogType.Warning); - - // 尝试加载备份 - if (File.Exists(PluginConfigBackupFile)) - { - try - { - string backupJson = File.ReadAllText(PluginConfigBackupFile); - var backupStates = JsonConvert.DeserializeObject>(backupJson); - - if (backupStates != null && backupStates.Count > 0) - { - PluginStates = backupStates; - _configDirty = true; // 从备份加载,需要重新保存主配置 - LogHelper.WriteLogToFile($"已从备份恢复 {PluginStates.Count} 个插件状态"); - return; // 成功从备份加载,提前退出 - } - } - catch (Exception backupEx) - { - LogHelper.WriteLogToFile($"从备份恢复配置失败: {backupEx.Message}", LogHelper.LogType.Error); - } - } - - PluginStates = defaultConfig; - _configDirty = true; - LogHelper.WriteLogToFile("使用默认空配置", LogHelper.LogType.Warning); - } - - // 没有成功加载或使用备份,使用默认配置 - break; - } - catch (Exception ex) - { - if (attempt < maxRetries) - { - LogHelper.WriteLogToFile($"加载配置失败 (尝试 {attempt}/{maxRetries}): {ex.Message},将在 {retryDelayMs}ms 后重试", LogHelper.LogType.Warning); - Thread.Sleep(retryDelayMs); - } - else - { - LogHelper.WriteLogToFile($"加载插件配置失败,已达最大重试次数 ({maxRetries}): {ex.Message}", LogHelper.LogType.Error); - - // 最终失败,使用默认配置 - PluginStates = defaultConfig; - _configDirty = true; - } - } - } - } - finally - { - // 释放配置锁 - _configLock.Release(); - } - } - - /// - /// 异步保存插件配置 - /// - public async Task SaveConfigAsync() - { - // 如果配置没有变化,无需保存 - if (!_configDirty) - { - return; - } - - // 尝试获取配置锁(异步) - if (!await _configLock.WaitAsync(0)) - { - // 已有保存操作在进行中,触发自动保存延迟 - TriggerAutoSave(); - return; - } - - try - { - // 创建配置任务 - await Task.Run(() => SaveConfig()); - } - finally - { - // 释放配置锁 - _configLock.Release(); - } - } - - /// - /// 保存插件配置 - /// - public void SaveConfig() - { - // 如果配置没有变化,无需保存 - if (!_configDirty) - { - return; - } - - const int maxRetries = 3; // 最大重试次数 - const int retryDelayMs = 500; // 重试延迟时间(毫秒) - - try - { - LogHelper.WriteLogToFile($"开始保存插件配置到: {PluginConfigFile}"); - - // 生成JSON数据 - string json = JsonConvert.SerializeObject(PluginStates, Formatting.Indented); - string tempFile = PluginConfigFile + ".temp"; // 临时文件路径 - - // 确保目录存在 - string configDir = Path.GetDirectoryName(PluginConfigFile); - if (!Directory.Exists(configDir)) - { - Directory.CreateDirectory(configDir); - LogHelper.WriteLogToFile($"创建配置目录: {configDir}"); - } - - // 先备份当前配置 - try - { - if (File.Exists(PluginConfigFile)) - { - File.Copy(PluginConfigFile, PluginConfigBackupFile, true); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"备份配置文件失败: {ex.Message}", LogHelper.LogType.Warning); - } - - for (int attempt = 1; attempt <= maxRetries; attempt++) - { - try - { - // 直接写入目标文件 - File.WriteAllText(PluginConfigFile, json); - - // 验证写入是否成功 - if (File.Exists(PluginConfigFile)) - { - // 重置脏标记 - _configDirty = false; - LogHelper.WriteLogToFile($"插件配置已成功保存到磁盘: {PluginConfigFile}, 共 {PluginStates.Count} 个插件状态"); - return; - } - } - catch (Exception ex) - { - if (attempt < maxRetries) - { - LogHelper.WriteLogToFile($"保存配置失败 (尝试 {attempt}/{maxRetries}): {ex.Message},将在 {retryDelayMs}ms 后重试", LogHelper.LogType.Warning); - Thread.Sleep(retryDelayMs); - } - else - { - LogHelper.WriteLogToFile($"保存插件配置失败,已达最大重试次数 ({maxRetries}): {ex.Message}", LogHelper.LogType.Error); - - // 尝试使用临时文件方式 - try - { - // 删除可能存在的旧临时文件 - if (File.Exists(tempFile)) - { - File.Delete(tempFile); - } - - // 写入临时文件 - File.WriteAllText(tempFile, json); - - // 如果目标文件存在,先删除 - if (File.Exists(PluginConfigFile)) - { - File.Delete(PluginConfigFile); - } - - // 重命名临时文件 - File.Move(tempFile, PluginConfigFile); - - // 重置脏标记 - _configDirty = false; - LogHelper.WriteLogToFile($"使用临时文件方式成功保存配置: {PluginConfigFile}"); - return; - } - catch (Exception fallbackEx) - { - LogHelper.WriteLogToFile($"临时文件保存方式也失败: {fallbackEx.Message}", LogHelper.LogType.Error); - } - } - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"保存插件配置时发生未处理异常: {ex.Message}", LogHelper.LogType.Error); - } - } - - /// - /// 计算文件哈希 - /// - /// 文件路径 - /// 文件哈希值 - private string CalculateFileHash(string filePath) - { - try - { - using (var md5 = MD5.Create()) - using (var stream = File.OpenRead(filePath)) - { - byte[] hash = md5.ComputeHash(stream); - return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"计算文件哈希值时出错: {ex.Message}", LogHelper.LogType.Error); - return string.Empty; - } - } - - /// - /// 从配置文件重新加载所有插件状态并应用 - /// - public void ReloadPluginsFromConfig() - { - try - { - LogHelper.WriteLogToFile("开始从配置文件重新加载插件状态"); - - // 保存当前配置状态,以便在加载失败时回滚 - Dictionary previousStates = new Dictionary(PluginStates); - - // 重新加载配置文件 - LoadConfig(); - - // 如果配置文件加载失败,PluginStates可能为空,这时使用之前的状态 - if (PluginStates == null || PluginStates.Count == 0) - { - LogHelper.WriteLogToFile("加载的配置为空,恢复到之前的状态", LogHelper.LogType.Warning); - PluginStates = previousStates; - return; - } - - LogHelper.WriteLogToFile($"已加载 {PluginStates.Count} 个插件状态,开始应用..."); - - // 对比配置,查找变更的插件 - foreach (var plugin in Plugins.ToList()) // 创建副本进行遍历,避免集合修改异常 - { - string pluginTypeName = GetPluginStateKey(plugin); - - // 检查插件在配置中是否存在 - if (PluginStates.TryGetValue(pluginTypeName, out bool shouldBeEnabled)) - { - bool currentlyEnabled = plugin is PluginBase pluginBase && pluginBase.IsEnabled; - - // 如果状态需要变更 - if (currentlyEnabled != shouldBeEnabled) - { - LogHelper.WriteLogToFile($"应用插件 {plugin.Name} 的配置状态: {(shouldBeEnabled ? "启用" : "禁用")}"); - - if (shouldBeEnabled) - { - try - { - plugin.Enable(); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"启用插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - else - { - try - { - // 记录禁用信息,特别是内置插件 - bool isBuiltIn = plugin.IsBuiltIn; - LogHelper.WriteLogToFile($"尝试禁用{(isBuiltIn ? "内置" : "外部")}插件 {plugin.Name}"); - - // 禁用插件 - plugin.Disable(); - - // 对于内置插件,特别检查禁用状态 - if (isBuiltIn && plugin is PluginBase builtInPluginBase) - { - if (builtInPluginBase.IsEnabled) - { - LogHelper.WriteLogToFile($"内置插件 {plugin.Name} 禁用失败,尝试强制禁用", LogHelper.LogType.Warning); - // 强制设置禁用状态 - var enabledProperty = typeof(PluginBase).GetProperty("IsEnabled"); - if (enabledProperty != null) - { - enabledProperty.SetValue(builtInPluginBase, false); - LogHelper.WriteLogToFile($"已通过反射强制禁用内置插件 {plugin.Name}"); - } - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"禁用插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - // 如果是外部插件,执行重载 - if (!plugin.IsBuiltIn && plugin is PluginBase externalPlugin && !string.IsNullOrEmpty(externalPlugin.PluginPath)) - { - try - { - ReloadPlugin(externalPlugin); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重载外部插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - } - } - else - { - // 插件不在配置中,将其添加为禁用状态 - PluginStates[pluginTypeName] = false; - LogHelper.WriteLogToFile($"插件 {plugin.Name} 不在配置中,默认设置为禁用状态"); - - // 如果当前是启用状态,则禁用它 - if (plugin is PluginBase pluginBase && pluginBase.IsEnabled) - { - try - { - bool isBuiltIn = plugin.IsBuiltIn; - LogHelper.WriteLogToFile($"尝试禁用未配置的{(isBuiltIn ? "内置" : "外部")}插件 {plugin.Name}"); - - plugin.Disable(); - - // 对于内置插件,特别检查禁用状态 - if (isBuiltIn && pluginBase.IsEnabled) - { - LogHelper.WriteLogToFile($"未配置的内置插件 {plugin.Name} 禁用失败,尝试强制禁用", LogHelper.LogType.Warning); - // 强制设置禁用状态 - var enabledProperty = typeof(PluginBase).GetProperty("IsEnabled"); - if (enabledProperty != null) - { - enabledProperty.SetValue(pluginBase, false); - LogHelper.WriteLogToFile($"已通过反射强制禁用未配置的内置插件 {plugin.Name}"); - } - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"禁用未配置插件 {plugin.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - } - } - - // 保存更新后的配置 - SaveConfig(); - - // 通知UI更新 - if (Application.Current != null && Application.Current.Dispatcher != null) - { - Application.Current.Dispatcher.Invoke(() => - { - // 通知任何可能打开的插件设置窗口刷新 - foreach (Window window in Application.Current.Windows) - { - if (window is PluginSettingsWindow pluginWindow) - { - pluginWindow.RefreshPluginList(); - } - } - }); - } - - LogHelper.WriteLogToFile("插件状态已从配置文件重新加载完成"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"从配置文件重新加载插件状态时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - } -} \ No newline at end of file diff --git a/Ink Canvas/Helpers/Plugins/PluginRuntime.cs b/Ink Canvas/Helpers/Plugins/PluginRuntime.cs deleted file mode 100644 index a3ea7ec2..00000000 --- a/Ink Canvas/Helpers/Plugins/PluginRuntime.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 在加载任何 SDK 插件之前初始化宿主上下文(实现 )。 - /// - public static class PluginRuntime - { - private static PluginSdkHostContext _context; - - public static PluginSdkHostContext SdkContext => _context; - - /// 相同实例,便于旧代码通过 访问。 - public static IPluginService Services => SdkContext != null ? (IPluginService)SdkContext : null; - - public static void Initialize(MainWindow mainWindow) - { - if (_context == null) - { - _context = new PluginSdkHostContext(); - } - - _context.SetMainWindow(mainWindow); - } - } -} diff --git a/Ink Canvas/Helpers/Plugins/PluginSdkHostContext.cs b/Ink Canvas/Helpers/Plugins/PluginSdkHostContext.cs deleted file mode 100644 index e5b9db97..00000000 --- a/Ink Canvas/Helpers/Plugins/PluginSdkHostContext.cs +++ /dev/null @@ -1,1289 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Ink; -using Ink_Canvas.Windows; -using InkCanvasForClass.PluginSdk; -using LegacyNotificationType = Ink_Canvas.Helpers.Plugins.NotificationType; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 统一宿主上下文:同时实现 SDK 的 与旧版 。 - /// - public class PluginSdkHostContext : IPluginContext, IPluginService - { - private MainWindow _mainWindow; - private Dictionary _eventHandlers = new Dictionary(); - - /// - /// 设置主窗口引用 - /// - /// 主窗口实例 - public void SetMainWindow(MainWindow mainWindow) - { - _mainWindow = mainWindow; - } - - #region 窗口和UI访问 - - public Window MainWindow => _mainWindow; - - public System.Windows.Controls.InkCanvas CurrentCanvas => _mainWindow?.inkCanvas; - - public IList AllCanvasPages => - _mainWindow?.WhiteboardPages ?? new List(); - - public int CurrentPageIndex => _mainWindow?.CurrentPageIndex ?? 0; - - public int TotalPageCount => _mainWindow?.WhiteboardPages?.Count ?? 0; - - public FrameworkElement FloatingToolBar => _mainWindow?.ViewboxFloatingBar; - - public FrameworkElement LeftPanel => _mainWindow?.BlackboardLeftSide; - - public FrameworkElement RightPanel => _mainWindow?.BlackboardRightSide; - - public FrameworkElement TopPanel => _mainWindow?.BorderTools; - - public FrameworkElement BottomPanel => _mainWindow?.BorderSettings; - - #endregion - - #region 绘制工具状态 - - public int CurrentDrawingMode => GetCurrentDrawingMode(); - - public double CurrentInkWidth => GetCurrentInkWidth(); - - public Color CurrentInkColor => GetCurrentInkColor(); - - public double CurrentHighlighterWidth => GetCurrentHighlighterWidth(); - - public int CurrentEraserSize => GetCurrentEraserSize(); - - public int CurrentEraserType => GetCurrentEraserType(); - - public int CurrentEraserShape => GetCurrentEraserShape(); - - public double CurrentInkAlpha => GetCurrentInkAlpha(); - - public int CurrentInkStyle => GetCurrentInkStyle(); - - public string CurrentBackgroundColor => GetCurrentBackgroundColor(); - - #endregion - - #region 应用状态 - - public bool IsDarkTheme => GetIsDarkTheme(); - - public bool IsWhiteboardMode => GetIsWhiteboardMode(); - - public bool IsPPTMode => GetIsPPTMode(); - - public bool IsFullScreenMode => GetIsFullScreenMode(); - - public bool IsCanvasMode => GetIsCanvasMode(); - - public bool IsSelectionMode => GetIsSelectionMode(); - - public bool IsEraserMode => GetIsEraserMode(); - - public bool IsShapeDrawingMode => GetIsShapeDrawingMode(); - - public bool IsHighlighterMode => GetIsHighlighterMode(); - - #endregion - - #region 操作状态 - - public bool CanUndo => GetCanUndo(); - - public bool CanRedo => GetCanRedo(); - - #endregion - - #region 设置管理 - - public T GetSetting(string key, T defaultValue = default(T)) - { - try - { - // 这里需要根据实际的设置系统来实现 - // 暂时返回默认值 - return defaultValue; - } - catch - { - return defaultValue; - } - } - - public void SetSetting(string key, T value) - { - try - { - // 这里需要根据实际的设置系统来实现 - LogHelper.WriteLogToFile($"设置 {key} = {value}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置 {key} 时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SaveSettings() - { - try - { - // 这里需要根据实际的设置系统来实现 - LogHelper.WriteLogToFile("设置已保存"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"保存设置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void LoadSettings() - { - try - { - // 这里需要根据实际的设置系统来实现 - LogHelper.WriteLogToFile("设置已加载"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载设置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ResetSettings() - { - try - { - // 这里需要根据实际的设置系统来实现 - LogHelper.WriteLogToFile("设置已重置"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重置设置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 插件管理 - - public IList GetAllPlugins() - { - return PluginManager.Instance.GetAllSdkPluginInstances().ToList(); - } - - public IInkCanvasPlugin GetPlugin(string pluginName) - { - return PluginManager.Instance.GetSdkPluginByName(pluginName); - } - - public void EnablePlugin(string pluginName) - { - if (PluginManager.Instance.GetSdkPluginByName(pluginName) != null) - { - PluginManager.Instance.SetSdkPluginEnabledByName(pluginName, true); - return; - } - - var plugin = PluginManager.Instance.Plugins.FirstOrDefault(p => p.Name == pluginName); - if (plugin != null) - { - PluginManager.Instance.TogglePlugin(plugin, true); - } - } - - public void DisablePlugin(string pluginName) - { - if (PluginManager.Instance.GetSdkPluginByName(pluginName) != null) - { - PluginManager.Instance.SetSdkPluginEnabledByName(pluginName, false); - return; - } - - var plugin = PluginManager.Instance.Plugins.FirstOrDefault(p => p.Name == pluginName); - if (plugin != null) - { - PluginManager.Instance.TogglePlugin(plugin, false); - } - } - - public void UnloadPlugin(string pluginName) - { - if (PluginManager.Instance.GetSdkPluginByName(pluginName) != null) - { - PluginManager.Instance.UnloadSdkPluginByName(pluginName); - return; - } - - var plugin = PluginManager.Instance.Plugins.FirstOrDefault(p => p.Name == pluginName); - if (plugin != null) - { - PluginManager.Instance.UnloadPlugin(plugin, true); - } - } - - #endregion - - #region 窗口操作 - - public void ShowSettingsWindow() - { - try - { - if (_mainWindow == null) - { - return; - } - - _mainWindow.Dispatcher.BeginInvoke(new Action(() => _mainWindow.BtnSettings_Click(null, null))); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示设置窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void HideSettingsWindow() - { - try - { - if (_mainWindow == null) - { - return; - } - - _mainWindow.Dispatcher.BeginInvoke(new Action(() => _mainWindow.HideSubPanels())); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"隐藏设置窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ShowPluginSettingsWindow() - { - try - { - if (_mainWindow == null) - { - return; - } - - _mainWindow.Dispatcher.BeginInvoke(new Action(() => - { - var w = new PluginSettingsWindow { Owner = _mainWindow }; - w.Show(); - })); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示插件设置窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void HidePluginSettingsWindow() - { - try - { - var app = Application.Current; - if (app?.Dispatcher == null) - { - return; - } - - app.Dispatcher.BeginInvoke(new Action(() => - { - foreach (Window w in app.Windows) - { - if (w is PluginSettingsWindow psw) - { - psw.Close(); - } - } - })); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"隐藏插件设置窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ShowHelpWindow() - { - try - { - // 这里需要调用帮助窗口显示方法 - LogHelper.WriteLogToFile("显示帮助窗口"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示帮助窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void HideHelpWindow() - { - try - { - // 这里需要调用帮助窗口隐藏方法 - LogHelper.WriteLogToFile("隐藏帮助窗口"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"隐藏帮助窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ShowAboutWindow() - { - try - { - // 这里需要调用关于窗口显示方法 - LogHelper.WriteLogToFile("显示关于窗口"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示关于窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void HideAboutWindow() - { - try - { - // 这里需要调用关于窗口隐藏方法 - LogHelper.WriteLogToFile("隐藏关于窗口"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"隐藏关于窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ShowNotification(string message, InkCanvasForClass.PluginSdk.NotificationType type = InkCanvasForClass.PluginSdk.NotificationType.Info) - { - try - { - LogHelper.WriteLogToFile($"通知: {message} ({type})"); - var title = type.ToString(); - _mainWindow?.PluginHost_ShowInfo(title, message); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示通知时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public bool ShowConfirmDialog(string message, string title = "确认") - { - try - { - return _mainWindow != null && _mainWindow.PluginHost_ShowConfirm(title, message); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示确认对话框时出错: {ex.Message}", LogHelper.LogType.Error); - return false; - } - } - - public string ShowInputDialog(string message, string title = "输入", string defaultValue = "") - { - try - { - return _mainWindow != null - ? _mainWindow.PluginHost_ShowInput(title, message, defaultValue) - : defaultValue; - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"显示输入对话框时出错: {ex.Message}", LogHelper.LogType.Error); - return defaultValue; - } - } - - public void SetFullScreen(bool isFullScreen) - { - try - { - if (_mainWindow == null) - { - return; - } - - _mainWindow.Dispatcher.Invoke(() => - { - _mainWindow.WindowState = isFullScreen ? WindowState.Maximized : WindowState.Normal; - }); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置全屏时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetTopMost(bool isTopMost) - { - try - { - if (_mainWindow == null) - { - return; - } - - _mainWindow.Dispatcher.Invoke(() => _mainWindow.Topmost = isTopMost); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置置顶时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetWindowVisibility(bool isVisible) - { - try - { - if (_mainWindow == null) - { - return; - } - - _mainWindow.Dispatcher.Invoke(() => - _mainWindow.Visibility = isVisible ? Visibility.Visible : Visibility.Hidden); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置窗口可见性时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void MinimizeWindow() - { - try - { - if (_mainWindow != null) - { - _mainWindow.WindowState = WindowState.Minimized; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"最小化窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void MaximizeWindow() - { - try - { - if (_mainWindow != null) - { - _mainWindow.WindowState = WindowState.Maximized; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"最大化窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void RestoreWindow() - { - try - { - if (_mainWindow != null) - { - _mainWindow.WindowState = WindowState.Normal; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"还原窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void CloseWindow() - { - try - { - _mainWindow?.Close(); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"关闭窗口时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetWindowPosition(double x, double y) - { - try - { - if (_mainWindow != null) - { - _mainWindow.Left = x; - _mainWindow.Top = y; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置窗口位置时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetWindowSize(double width, double height) - { - try - { - if (_mainWindow != null) - { - _mainWindow.Width = width; - _mainWindow.Height = height; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置窗口大小时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public (double x, double y) GetWindowPosition() - { - try - { - if (_mainWindow != null) - { - return (_mainWindow.Left, _mainWindow.Top); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"获取窗口位置时出错: {ex.Message}", LogHelper.LogType.Error); - } - return (0, 0); - } - - public (double width, double height) GetWindowSize() - { - try - { - if (_mainWindow != null) - { - return (_mainWindow.Width, _mainWindow.Height); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"获取窗口大小时出错: {ex.Message}", LogHelper.LogType.Error); - } - return (800, 600); - } - - #endregion - - #region 画布操作 - - public void ClearCanvas() - { - try - { - _mainWindow?.PluginHost_ClearInk(false); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"清除画布时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ClearAllCanvases() - { - try - { - // 这里需要调用清除所有画布的方法 - LogHelper.WriteLogToFile("清除所有画布"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"清除所有画布时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void AddNewPage() - { - try - { - // 这里需要调用添加新页面的方法 - LogHelper.WriteLogToFile("添加新页面"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"添加新页面时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void DeleteCurrentPage() - { - try - { - // 这里需要调用删除当前页面的方法 - LogHelper.WriteLogToFile("删除当前页面"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"删除当前页面时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SwitchToPage(int pageIndex) - { - try - { - // 这里需要调用切换页面的方法 - LogHelper.WriteLogToFile($"切换到页面: {pageIndex}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"切换页面时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void NextPage() - { - try - { - // 这里需要调用下一页的方法 - LogHelper.WriteLogToFile("下一页"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"下一页时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void PreviousPage() - { - try - { - // 这里需要调用上一页的方法 - LogHelper.WriteLogToFile("上一页"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"上一页时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 绘制设置 - - public void SetDrawingMode(int mode) - { - try - { - // 这里需要调用设置绘制模式的方法 - LogHelper.WriteLogToFile($"设置绘制模式: {mode}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置绘制模式时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetInkWidth(double width) - { - try - { - // 这里需要调用设置墨迹宽度的方法 - LogHelper.WriteLogToFile($"设置墨迹宽度: {width}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置墨迹宽度时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetInkColor(Color color) - { - try - { - // 这里需要调用设置墨迹颜色的方法 - LogHelper.WriteLogToFile($"设置墨迹颜色: {color}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置墨迹颜色时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetHighlighterWidth(double width) - { - try - { - // 这里需要调用设置高亮笔宽度的方法 - LogHelper.WriteLogToFile($"设置高亮笔宽度: {width}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置高亮笔宽度时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetEraserSize(int size) - { - try - { - // 这里需要调用设置橡皮擦大小的方法 - LogHelper.WriteLogToFile($"设置橡皮擦大小: {size}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置橡皮擦大小时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetEraserType(int type) - { - try - { - // 这里需要调用设置橡皮擦类型的方法 - LogHelper.WriteLogToFile($"设置橡皮擦类型: {type}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置橡皮擦类型时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetEraserShape(int shape) - { - try - { - // 这里需要调用设置橡皮擦形状的方法 - LogHelper.WriteLogToFile($"设置橡皮擦形状: {shape}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置橡皮擦形状时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetInkAlpha(double alpha) - { - try - { - // 这里需要调用设置墨迹透明度的方法 - LogHelper.WriteLogToFile($"设置墨迹透明度: {alpha}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置墨迹透明度时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetInkStyle(int style) - { - try - { - // 这里需要调用设置墨迹样式的方法 - LogHelper.WriteLogToFile($"设置墨迹样式: {style}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置墨迹样式时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SetBackgroundColor(string color) - { - try - { - // 这里需要调用设置背景颜色的方法 - LogHelper.WriteLogToFile($"设置背景颜色: {color}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"设置背景颜色时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 文件操作 - - public void SaveCanvas(string filePath) - { - try - { - // 这里需要调用保存画布的方法 - LogHelper.WriteLogToFile($"保存画布到: {filePath}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"保存画布时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void LoadCanvas(string filePath) - { - try - { - // 这里需要调用加载画布的方法 - LogHelper.WriteLogToFile($"加载画布从: {filePath}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"加载画布时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ExportAsImage(string filePath, string format) - { - try - { - // 这里需要调用导出为图片的方法 - LogHelper.WriteLogToFile($"导出为图片: {filePath} ({format})"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"导出为图片时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ExportAsPDF(string filePath) - { - try - { - // 这里需要调用导出为PDF的方法 - LogHelper.WriteLogToFile($"导出为PDF: {filePath}"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"导出为PDF时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 编辑操作 - - public void Undo() - { - try - { - _mainWindow?.PluginHost_Undo(); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"撤销操作时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void Redo() - { - try - { - _mainWindow?.PluginHost_Redo(); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重做操作时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void SelectAll() - { - try - { - // 这里需要调用全选的方法 - LogHelper.WriteLogToFile("全选"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"全选时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void DeselectAll() - { - try - { - // 这里需要调用取消选择的方法 - LogHelper.WriteLogToFile("取消选择"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"取消选择时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void DeleteSelected() - { - try - { - // 这里需要调用删除选中项的方法 - LogHelper.WriteLogToFile("删除选中项"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"删除选中项时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void CopySelected() - { - try - { - // 这里需要调用复制选中项的方法 - LogHelper.WriteLogToFile("复制选中项"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"复制选中项时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void CutSelected() - { - try - { - // 这里需要调用剪切选中项的方法 - LogHelper.WriteLogToFile("剪切选中项"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"剪切选中项时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void Paste() - { - try - { - // 这里需要调用粘贴的方法 - LogHelper.WriteLogToFile("粘贴"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"粘贴时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 事件系统 - - public void RegisterEventHandler(string eventName, EventHandler handler) - { - try - { - if (!_eventHandlers.ContainsKey(eventName)) - { - _eventHandlers[eventName] = handler; - } - else - { - _eventHandlers[eventName] += handler; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"注册事件处理器时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void UnregisterEventHandler(string eventName, EventHandler handler) - { - try - { - if (_eventHandlers.ContainsKey(eventName)) - { - _eventHandlers[eventName] -= handler; - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"注销事件处理器时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void TriggerEvent(string eventName, object sender, EventArgs args) - { - try - { - if (_eventHandlers.ContainsKey(eventName)) - { - _eventHandlers[eventName]?.Invoke(sender, args); - } - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"触发事件时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 应用程序操作 - - public void RestartApplication() - { - try - { - var path = Process.GetCurrentProcess().MainModule?.FileName; - if (!string.IsNullOrEmpty(path)) - { - Process.Start(new ProcessStartInfo - { - FileName = path, - UseShellExecute = true - }); - } - - Application.Current?.Shutdown(0); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"重启应用程序时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void ExitApplication() - { - try - { - Application.Current?.Shutdown(0); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"退出应用程序时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void CheckForUpdates() - { - try - { - // 这里需要调用检查更新的方法 - LogHelper.WriteLogToFile("检查更新"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"检查更新时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void OpenHelpDocument() - { - try - { - // 这里需要调用打开帮助文档的方法 - LogHelper.WriteLogToFile("打开帮助文档"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"打开帮助文档时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - public void OpenAboutPage() - { - try - { - // 这里需要调用打开关于页面的方法 - LogHelper.WriteLogToFile("打开关于页面"); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"打开关于页面时出错: {ex.Message}", LogHelper.LogType.Error); - } - } - - #endregion - - #region 私有方法 - 获取当前状态 - - private int GetCurrentDrawingMode() - { - // 这里需要根据实际的绘制模式状态来实现 - return 0; - } - - private double GetCurrentInkWidth() - { - // 这里需要根据实际的墨迹宽度状态来实现 - return 2.5; - } - - private Color GetCurrentInkColor() - { - // 这里需要根据实际的墨迹颜色状态来实现 - return Colors.Black; - } - - private double GetCurrentHighlighterWidth() - { - // 这里需要根据实际的高亮笔宽度状态来实现 - return 20.0; - } - - private int GetCurrentEraserSize() - { - // 这里需要根据实际的橡皮擦大小状态来实现 - return 2; - } - - private int GetCurrentEraserType() - { - // 这里需要根据实际的橡皮擦类型状态来实现 - return 0; - } - - private int GetCurrentEraserShape() - { - // 这里需要根据实际的橡皮擦形状状态来实现 - return 0; - } - - private double GetCurrentInkAlpha() - { - // 这里需要根据实际的墨迹透明度状态来实现 - return 255.0; - } - - private int GetCurrentInkStyle() - { - // 这里需要根据实际的墨迹样式状态来实现 - return 0; - } - - private string GetCurrentBackgroundColor() - { - // 这里需要根据实际的背景颜色状态来实现 - return "#162924"; - } - - private bool GetIsDarkTheme() - { - // 这里需要根据实际的主题状态来实现 - return false; - } - - private bool GetIsWhiteboardMode() - { - // 这里需要根据实际的白板模式状态来实现 - return false; - } - - private bool GetIsPPTMode() - { - // 这里需要根据实际的PPT模式状态来实现 - return false; - } - - private bool GetIsFullScreenMode() - { - // 这里需要根据实际的全屏模式状态来实现 - return false; - } - - private bool GetIsCanvasMode() - { - // 这里需要根据实际的画布模式状态来实现 - return true; - } - - private bool GetIsSelectionMode() - { - // 这里需要根据实际的选择模式状态来实现 - return false; - } - - private bool GetIsEraserMode() - { - // 这里需要根据实际的橡皮擦模式状态来实现 - return false; - } - - private bool GetIsShapeDrawingMode() - { - // 这里需要根据实际的形状绘制模式状态来实现 - return false; - } - - private bool GetIsHighlighterMode() - { - // 这里需要根据实际的高亮笔模式状态来实现 - return false; - } - - private bool GetCanUndo() - { - return _mainWindow?.PluginHost_CanUndo() ?? false; - } - - private bool GetCanRedo() - { - return _mainWindow?.PluginHost_CanRedo() ?? false; - } - - #endregion - - #region IPluginService / IGetService 显式实现 - - List IGetService.GetAllPlugins() - { - return PluginManager.Instance.Plugins.ToList(); - } - - IPlugin IGetService.GetPlugin(string pluginName) - { - return PluginManager.Instance.Plugins.FirstOrDefault(p => p.Name == pluginName); - } - - List IGetService.AllCanvasPages - { - get - { - var pages = AllCanvasPages; - return pages == null ? new List() : pages.ToList(); - } - } - - global::System.Windows.Controls.InkCanvas IGetService.CurrentCanvas => CurrentCanvas; - - void IWindowService.ShowNotification(string message, LegacyNotificationType type) - { - ShowNotification(message, MapLegacyNotification(type)); - } - - private static InkCanvasForClass.PluginSdk.NotificationType MapLegacyNotification(LegacyNotificationType type) - { - switch (type) - { - case LegacyNotificationType.Success: - return InkCanvasForClass.PluginSdk.NotificationType.Success; - case LegacyNotificationType.Warning: - return InkCanvasForClass.PluginSdk.NotificationType.Warning; - case LegacyNotificationType.Error: - return InkCanvasForClass.PluginSdk.NotificationType.Error; - default: - return InkCanvasForClass.PluginSdk.NotificationType.Info; - } - } - - #endregion - } -} diff --git a/Ink Canvas/Helpers/Plugins/PluginServiceManager.cs b/Ink Canvas/Helpers/Plugins/PluginServiceManager.cs deleted file mode 100644 index cb2cb2ef..00000000 --- a/Ink Canvas/Helpers/Plugins/PluginServiceManager.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 兼容旧代码的薄门面:与 为同一实例,实现 。 - /// - public static class PluginServiceManager - { - public static IPluginService Instance - { - get - { - var ctx = PluginRuntime.SdkContext; - if (ctx == null) - { - throw new InvalidOperationException("插件宿主尚未初始化:请先调用 PluginRuntime.Initialize(MainWindow)。"); - } - - return (IPluginService)ctx; - } - } - } -} diff --git a/Ink Canvas/Helpers/Plugins/SdkPluginAdapter.cs b/Ink Canvas/Helpers/Plugins/SdkPluginAdapter.cs deleted file mode 100644 index 11e20961..00000000 --- a/Ink Canvas/Helpers/Plugins/SdkPluginAdapter.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Windows.Controls; -using InkCanvasForClass.PluginHost; -using InkCanvasForClass.PluginSdk; - -namespace Ink_Canvas.Helpers.Plugins -{ - /// - /// 将基于 的外部插件适配为宿主统一的 。 - /// - public sealed class SdkPluginAdapter : PluginBase - { - private readonly IInkCanvasPlugin _core; - private readonly string _folderId; - - public SdkPluginAdapter(string folderId, IInkCanvasPlugin core, string mainAssemblyPath) - { - _folderId = folderId ?? throw new ArgumentNullException(nameof(folderId)); - _core = core ?? throw new ArgumentNullException(nameof(core)); - PluginPath = mainAssemblyPath ?? string.Empty; - } - - public string FolderId => _folderId; - - public IInkCanvasPlugin Core => _core; - - public override string PluginStateKey => "SdkFolder:" + _folderId; - - public override string Name => _core.Name; - - public override string Description => _core.Description; - - public override Version Version => _core.Version; - - public override string Author => _core.Author; - - public override bool IsBuiltIn => false; - - public override void Initialize() - { - base.Initialize(); - - var ctx = PluginRuntime.SdkContext; - if (ctx == null) - { - LogHelper.WriteLogToFile($"SDK 插件 {_core.Name} 初始化失败:宿主上下文未就绪", LogHelper.LogType.Error); - return; - } - - _core.Initialize(ctx); - - var registry = PluginManager.Instance.ExtensionRegistry; - registry.SetCurrentPluginId(_folderId); - try - { - if (_core is InkCanvasPluginBase pluginBase) - { - pluginBase.RegisterExtensions(registry); - } - } - finally - { - registry.SetCurrentPluginId(string.Empty); - } - } - - public override void Enable() - { - if (IsEnabled) - { - return; - } - - if (_core is InkCanvasPluginBase b) - { - b.IsEnabled = true; - } - else - { - _core.Start(); - } - - base.Enable(); - } - - public override void Disable() - { - if (!IsEnabled) - { - return; - } - - if (_core is InkCanvasPluginBase b) - { - b.IsEnabled = false; - } - else - { - _core.Stop(); - } - - base.Disable(); - } - - public override UserControl GetSettingsView() - { - return _core.GetSettingsView(); - } - - public override void Cleanup() - { - try - { - if (_core is InkCanvasPluginBase b) - { - b.IsEnabled = false; - } - else - { - _core.Stop(); - } - - _core.Cleanup(); - } - catch (Exception ex) - { - LogHelper.WriteLogToFile($"SDK 插件 {_core.Name} Cleanup 出错: {ex.Message}", LogHelper.LogType.Error); - } - - base.Cleanup(); - } - } -} diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj index 962ca671..47bdc078 100644 --- a/Ink Canvas/InkCanvasForClass.csproj +++ b/Ink Canvas/InkCanvasForClass.csproj @@ -157,10 +157,6 @@ - - - - {F935DC20-1CF0-11D0-ADB9-00C04FD58A0B} diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 698fd6da..070af88d 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -247,21 +247,6 @@ - - -