From aa0bb22cdddb3d073df7f3d9a2fcd62f4a562240 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 18 Oct 2025 18:26:13 +0800 Subject: [PATCH] =?UTF-8?q?add:UIA=E7=AA=97=E5=8F=A3=E7=BD=AE=E9=A1=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/App.xaml.cs | 31 +++- Ink Canvas/Helpers/UIAccessDllExtractor.cs | 165 ++++++++++++++++++ Ink Canvas/InkCanvasForClass.csproj | 2 + Ink Canvas/MainWindow.xaml | 8 + Ink Canvas/MainWindow.xaml.cs | 105 +++++++++++ .../MainWindow_cs/MW_FloatingBarIcons.cs | 2 +- Ink Canvas/Resources/Settings.cs | 3 + Ink Canvas/UIAccessDLL_x64.dll | Bin 0 -> 14336 bytes Ink Canvas/UIAccessDLL_x86.dll | Bin 0 -> 11264 bytes 9 files changed, 312 insertions(+), 4 deletions(-) create mode 100644 Ink Canvas/Helpers/UIAccessDllExtractor.cs create mode 100644 Ink Canvas/UIAccessDLL_x64.dll create mode 100644 Ink Canvas/UIAccessDLL_x86.dll diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index 1e04932d..973fd1ee 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -41,6 +41,8 @@ namespace Ink_Canvas private static Process watchdogProcess; // 新增:标记是否为软件内主动退出 public static bool IsAppExitByUser; + // 新增:标记是否启用了UIA置顶功能 + public static bool IsUIAccessTopMostEnabled; // 新增:退出信号文件路径 private static string watchdogExitSignalFile = Path.Combine(Path.GetTempPath(), "icc_watchdog_exit_" + Process.GetCurrentProcess().Id + ".flag"); // 新增:崩溃日志文件路径 @@ -629,7 +631,7 @@ namespace Ink_Canvas LogHelper.WriteLogToFile("App | 检测到最终应用启动(更新后的应用)"); } - // 在应用启动时自动释放IACore相关DLL + // 释放IACore相关DLL if (_isSplashScreenShown) { SetSplashMessage("正在初始化组件..."); @@ -645,6 +647,22 @@ namespace Ink_Canvas LogHelper.WriteLogToFile($"释放IACore DLL时出错: {ex.Message}", LogHelper.LogType.Error); } + // 释放UIAccess DLL + if (_isSplashScreenShown) + { + SetSplashMessage("正在初始化组件..."); + SetSplashProgress(50); + await Task.Delay(300); + } + try + { + UIAccessDllExtractor.ExtractUIAccessDlls(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error); + } + // 记录应用启动(设备标识符) if (_isSplashScreenShown) { @@ -1055,7 +1073,15 @@ namespace Ink_Canvas Thread.Sleep(2000); } // 主进程异常退出,自动重启前判断崩溃后操作 - SyncCrashActionFromSettings(); // 新增:同步设置 + SyncCrashActionFromSettings(); // 同步设置 + + if (IsUIAccessTopMostEnabled) + { + string exePath = Process.GetCurrentProcess().MainModule.FileName; + Process.Start(exePath); + Environment.Exit(0); + } + if (CrashAction == CrashActionType.SilentRestart) { StartupCount.Increment(); @@ -1068,7 +1094,6 @@ namespace Ink_Canvas string exePath = Process.GetCurrentProcess().MainModule.FileName; Process.Start(exePath); } - // CrashActionType.NoAction 时不重启,直接退出 } catch { } Environment.Exit(0); diff --git a/Ink Canvas/Helpers/UIAccessDllExtractor.cs b/Ink Canvas/Helpers/UIAccessDllExtractor.cs new file mode 100644 index 00000000..f9448167 --- /dev/null +++ b/Ink Canvas/Helpers/UIAccessDllExtractor.cs @@ -0,0 +1,165 @@ +using System; +using System.IO; +using System.Reflection; + +namespace Ink_Canvas.Helpers +{ + /// + /// UIAccess DLL释放器 + /// + public static class UIAccessDllExtractor + { + private static readonly string[] RequiredDlls = { + "UIAccessDLL_x64.dll", + "UIAccessDLL_x86.dll" + }; + + /// + /// 在应用启动时释放UIAccess相关DLL + /// + public static void ExtractUIAccessDlls() + { + try + { + string appDirectory = AppDomain.CurrentDomain.BaseDirectory; + LogHelper.WriteLogToFile("开始检查并释放UIAccess相关DLL文件"); + + foreach (string dllName in RequiredDlls) + { + string targetPath = Path.Combine(appDirectory, dllName); + + // 检查文件是否已存在且有效 + if (File.Exists(targetPath) && IsValidDll(targetPath)) + { + LogHelper.WriteLogToFile($"{dllName} 已存在且有效,跳过释放"); + continue; + } + + // 从嵌入资源中释放DLL + if (ExtractDllFromResource(dllName, targetPath)) + { + LogHelper.WriteLogToFile($"成功释放 {dllName} 到 {targetPath}"); + } + else + { + LogHelper.WriteLogToFile($"警告:无法释放 {dllName},可能影响UIA置顶功能", LogHelper.LogType.Warning); + } + } + + LogHelper.WriteLogToFile("UIAccess DLL释放检查完成"); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 从嵌入资源中提取DLL文件 + /// + private static bool ExtractDllFromResource(string dllName, string targetPath) + { + try + { + Assembly assembly = Assembly.GetExecutingAssembly(); + string resourceName = $"Ink_Canvas.{dllName}"; + + using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName)) + { + if (resourceStream == null) + { + LogHelper.WriteLogToFile($"未找到嵌入资源: {resourceName}", LogHelper.LogType.Warning); + return false; + } + + // 确保目标目录存在 + string targetDirectory = Path.GetDirectoryName(targetPath); + if (!Directory.Exists(targetDirectory)) + { + Directory.CreateDirectory(targetDirectory); + } + + // 写入文件 + using (FileStream fileStream = new FileStream(targetPath, FileMode.Create, FileAccess.Write)) + { + resourceStream.CopyTo(fileStream); + } + + return true; + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"从资源提取 {dllName} 失败: {ex.Message}", LogHelper.LogType.Error); + return false; + } + } + + /// + /// 检查DLL文件是否有效 + /// + private static bool IsValidDll(string filePath) + { + try + { + if (!File.Exists(filePath)) + return false; + + FileInfo fileInfo = new FileInfo(filePath); + + // 检查文件大小(空文件或过小的文件可能无效) + if (fileInfo.Length < 1024) // 小于1KB可能无效 + return false; + + // 简单检查PE头(DLL文件应该以MZ开头) + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + byte[] buffer = new byte[2]; + if (fs.Read(buffer, 0, 2) == 2) + { + return buffer[0] == 0x4D && buffer[1] == 0x5A; // "MZ" + } + } + + return false; + } + catch + { + return false; + } + } + + /// + /// 清理释放的DLL文件(可选,在应用退出时调用) + /// + public static void CleanupExtractedDlls() + { + try + { + string appDirectory = AppDomain.CurrentDomain.BaseDirectory; + + foreach (string dllName in RequiredDlls) + { + string filePath = Path.Combine(appDirectory, dllName); + + if (File.Exists(filePath)) + { + try + { + File.Delete(filePath); + LogHelper.WriteLogToFile($"已清理 {dllName}"); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"清理 {dllName} 失败: {ex.Message}", LogHelper.LogType.Warning); + } + } + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"清理UIAccess DLL时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + } +} diff --git a/Ink Canvas/InkCanvasForClass.csproj b/Ink Canvas/InkCanvasForClass.csproj index ac80bfbb..1c25b961 100644 --- a/Ink Canvas/InkCanvasForClass.csproj +++ b/Ink Canvas/InkCanvasForClass.csproj @@ -198,6 +198,8 @@ + + diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 76068083..44eec01e 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -610,6 +610,14 @@ IsOn="True" FontFamily="Microsoft YaHei UI" FontWeight="Bold" Toggled="ToggleSwitchAlwaysOnTop_Toggled" /> + + + + + whiteboardPages = new List(); private int currentPageIndex; @@ -550,6 +557,12 @@ namespace Ink_Canvas ToggleSwitchAlwaysOnTop.IsOn = Settings.Advanced.IsAlwaysOnTop; ApplyAlwaysOnTop(); + // 初始化UIA置顶开关 + ToggleSwitchUIAccessTopMost.IsOn = Settings.Advanced.EnableUIAccessTopMost; + UpdateUIAccessTopMostVisibility(); + + App.IsUIAccessTopMostEnabled = Settings.Advanced.EnableUIAccessTopMost; + // 初始化剪贴板监控 InitializeClipboardMonitoring(); @@ -2030,6 +2043,21 @@ namespace Ink_Canvas Settings.Advanced.IsAlwaysOnTop = toggle != null && toggle.IsOn; SaveSettingsToFile(); ApplyAlwaysOnTop(); + UpdateUIAccessTopMostVisibility(); + } + + private void ToggleSwitchUIAccessTopMost_Toggled(object sender, RoutedEventArgs e) + { + if (!isLoaded) return; + var toggle = sender as ToggleSwitch; + bool newValue = toggle != null && toggle.IsOn; + + Settings.Advanced.EnableUIAccessTopMost = newValue; + SaveSettingsToFile(); + ApplyUIAccessTopMost(); + + App.IsUIAccessTopMostEnabled = newValue; + } private void Window_Activated(object sender, EventArgs e) @@ -2923,5 +2951,82 @@ namespace Ink_Canvas } #endregion + + #region UIA置顶功能 + + /// + /// 更新UIA置顶开关的可见性 + /// + private void UpdateUIAccessTopMostVisibility() + { + try + { + var visibility = Settings.Advanced.IsAlwaysOnTop ? Visibility.Visible : Visibility.Collapsed; + + if (UIAccessTopMostPanel != null) + { + UIAccessTopMostPanel.Visibility = visibility; + } + + if (UIAccessTopMostDescription != null) + { + UIAccessTopMostDescription.Visibility = visibility; + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"更新UIA置顶开关可见性时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 应用UIA置顶功能 + /// + private void ApplyUIAccessTopMost() + { + try + { + if (Settings.Advanced.EnableUIAccessTopMost && Settings.Advanced.IsAlwaysOnTop) + { + // 检查是否以管理员权限运行 + var identity = WindowsIdentity.GetCurrent(); + var principal = new WindowsPrincipal(identity); + + if (principal.IsInRole(WindowsBuiltInRole.Administrator)) + { + try + { + // 调用UIAccess DLL + if (Environment.Is64BitProcess) + { + PrepareUIAccessX64(); + } + else + { + PrepareUIAccessX86(); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"启用UIA置顶功能时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + else + { + LogHelper.WriteLogToFile("UIA置顶功能需要管理员权限", LogHelper.LogType.Warning); + } + } + else + { + LogHelper.WriteLogToFile("UIA置顶功能已禁用", LogHelper.LogType.Trace); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"应用UIA置顶功能时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + #endregion } } diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 2dde2248..ccfbee7e 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -928,7 +928,7 @@ namespace Ink_Canvas #region 主要的工具按鈕事件 /// - /// 浮動工具欄的"套索選"按鈕事件,重定向到舊UI的BtnSelect_Click方法 + /// 浮動工具欄的"套索選"按鈕事件,重定向到舊UI的BtnSelect_Click方法 /// /// sender /// MouseButtonEventArgs diff --git a/Ink Canvas/Resources/Settings.cs b/Ink Canvas/Resources/Settings.cs index 32d02c87..ba633b85 100644 --- a/Ink Canvas/Resources/Settings.cs +++ b/Ink Canvas/Resources/Settings.cs @@ -591,6 +591,9 @@ namespace Ink_Canvas [JsonProperty("isAlwaysOnTop")] public bool IsAlwaysOnTop { get; set; } = true; + + [JsonProperty("enableUIAccessTopMost")] + public bool EnableUIAccessTopMost { get; set; } = false; } public class InkToShape diff --git a/Ink Canvas/UIAccessDLL_x64.dll b/Ink Canvas/UIAccessDLL_x64.dll new file mode 100644 index 0000000000000000000000000000000000000000..9edc84b8bc5c22bb83ea88b965718b83f6db8b6e GIT binary patch literal 14336 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 z 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 literal 0 HcmV?d00001 diff --git a/Ink Canvas/UIAccessDLL_x86.dll b/Ink Canvas/UIAccessDLL_x86.dll new file mode 100644 index 0000000000000000000000000000000000000000..48fe7e3e991b3b7d170decdd34fd4c37067758d1 GIT binary patch literal 11264 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 literal 0 HcmV?d00001