From 94142ec8a57a1592edfac4623b56f11e6e293f19 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sat, 2 May 2026 00:40:49 +0800 Subject: [PATCH] =?UTF-8?q?add:=E5=9F=BA=E4=BA=8EIPC=E7=9A=84IACore?= =?UTF-8?q?=E5=9C=A8net6=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/App.xaml.cs | 11 +++-- Ink Canvas/Helpers/AnimationsHelper.cs | 11 +---- Ink Canvas/Helpers/IpcIACoreClient.cs | 55 ++--------------------- Ink Canvas/Properties/Strings.resx | 2 +- InkCanvasForClass.IACoreHelper/Program.cs | 24 +--------- 5 files changed, 15 insertions(+), 88 deletions(-) diff --git a/Ink Canvas/App.xaml.cs b/Ink Canvas/App.xaml.cs index 905abd75..4e771ab7 100644 --- a/Ink Canvas/App.xaml.cs +++ b/Ink Canvas/App.xaml.cs @@ -1204,9 +1204,14 @@ namespace Ink_Canvas try { - LogHelper.WriteLogToFile("启动 IACore IPC 辅助进程"); - bool ipcStarted = IpcIACoreClient.Instance.Start(); - LogHelper.WriteLogToFile($"IACore IPC 辅助进程{(ipcStarted ? "启动成功" : "启动失败(将使用本地 IACore 回退)")}"); + var shapeMode = ShapeRecognitionRouter.FromSettingsInt( + Ink_Canvas.Windows.SettingsViews.Helpers.SettingsManager.Settings?.InkToShape?.ShapeRecognitionEngine ?? 0); + if (!ShapeRecognitionRouter.ResolveUseWinRt(shapeMode)) + { + LogHelper.WriteLogToFile("启动 IACore IPC 辅助进程"); + bool ipcStarted = IpcIACoreClient.Instance.Start(); + LogHelper.WriteLogToFile($"IACore IPC 辅助进程{(ipcStarted ? "启动成功" : "启动失败")}"); + } } catch (Exception ex) { diff --git a/Ink Canvas/Helpers/AnimationsHelper.cs b/Ink Canvas/Helpers/AnimationsHelper.cs index 076bd4fd..c7a36a8c 100644 --- a/Ink Canvas/Helpers/AnimationsHelper.cs +++ b/Ink Canvas/Helpers/AnimationsHelper.cs @@ -1,4 +1,3 @@ -using Ink_Canvas.Controls; using System; using System.Windows; using System.Windows.Media; @@ -8,15 +7,7 @@ namespace Ink_Canvas.Helpers { internal class AnimationsHelper { - private static UIElement ResolveAnimationTarget(UIElement element) - { - if (element is BoardMenuFrame frame) - { - frame.ApplyTemplate(); - return frame.AnimationTarget ?? element; - } - return element; - } + private static UIElement ResolveAnimationTarget(UIElement element) => element; public static void ShowWithFadeIn(UIElement element, double duration = 0.15) { diff --git a/Ink Canvas/Helpers/IpcIACoreClient.cs b/Ink Canvas/Helpers/IpcIACoreClient.cs index 9910c6f0..e320b80a 100644 --- a/Ink Canvas/Helpers/IpcIACoreClient.cs +++ b/Ink Canvas/Helpers/IpcIACoreClient.cs @@ -1,24 +1,16 @@ using System; -using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.IO.Pipes; -using System.Linq; using System.Threading; -using System.Threading.Tasks; using System.Windows; using System.Windows.Ink; using System.Windows.Media; namespace Ink_Canvas.Helpers { - /// - /// 通过 Named Pipe IPC 调用 32 位辅助进程 InkCanvasForClass.IACoreHelper.exe 进行 IACore 形状识别。 - /// 单例,线程安全,辅助进程崩溃后自动重启。 - /// public sealed class IpcIACoreClient : IDisposable { - // ── 单例 ────────────────────────────────────────────────────────────── private static IpcIACoreClient _instance; private static readonly object _instanceLock = new object(); @@ -34,35 +26,26 @@ namespace Ink_Canvas.Helpers } } - // ── 状态 ────────────────────────────────────────────────────────────── private Process _helperProcess; private readonly object _pipeLock = new object(); private bool _disposed; private bool _available; - // 辅助进程 EXE 的路径(与主 EXE 同目录) private static string HelperExePath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "InkCanvasForClass.IACoreHelper.exe"); - // Named Pipe 名称(含主进程 PID,保证唯一) private string PipeName => string.Format("ICC_IACoreHelper_{0}", Process.GetCurrentProcess().Id); private IpcIACoreClient() { } - // ── 公开 API ────────────────────────────────────────────────────────── - - /// 启动辅助进程,返回是否成功。 public bool Start() { if (_disposed) return false; - - // 已运行则无需重启,避免 Warmup + App 两处调用导致重复启动 if (IsAvailable) return true; if (!File.Exists(HelperExePath)) { - LogHelper.WriteLogToFile($"[IACoreIPC] 辅助进程不存在: {HelperExePath}", LogHelper.LogType.Warning); _available = false; return false; } @@ -70,13 +53,8 @@ namespace Ink_Canvas.Helpers return LaunchHelper(); } - /// 是否就绪(辅助进程运行中)。 public bool IsAvailable => _available && _helperProcess != null && !_helperProcess.HasExited; - /// - /// 发送笔画到辅助进程进行 IACore 形状识别。 - /// 超时或失败时返回 。 - /// public InkShapeRecognitionResult Recognize(StrokeCollection strokes) { if (strokes == null || strokes.Count == 0) @@ -84,32 +62,22 @@ namespace Ink_Canvas.Helpers EnsureHelperAlive(); if (!IsAvailable) - { - LogHelper.WriteLogToFile($"[IACoreIPC] Recognize 跳过:辅助进程不可用(strokes={strokes.Count})", LogHelper.LogType.Warning); return InkShapeRecognitionResult.Empty; - } lock (_pipeLock) { try { - LogHelper.WriteLogToFile($"[IACoreIPC] Recognize 请求:strokes={strokes.Count}"); - var result = SendRecognizeRequest(strokes); - LogHelper.WriteLogToFile( - $"[IACoreIPC] Recognize 响应:IsSuccess={result.IsSuccess}, Shape={result.ShapeName}, StrokesToRemove={result.StrokesToRemove?.Count ?? 0}"); - return result; + return SendRecognizeRequest(strokes); } - catch (Exception ex) + catch { - LogHelper.WriteLogToFile($"[IACoreIPC] 识别失败: {ex.GetType().Name}: {ex.Message}", LogHelper.LogType.Error); KillHelper(); return InkShapeRecognitionResult.Empty; } } } - // ── 内部实现 ────────────────────────────────────────────────────────── - private bool LaunchHelper() { try @@ -133,16 +101,12 @@ namespace Ink_Canvas.Helpers _helperProcess.EnableRaisingEvents = true; _helperProcess.Exited += OnHelperExited; - // 等待 Pipe 就绪(最多 3 s) bool pipeReady = WaitForPipe(3000); _available = pipeReady; - - LogHelper.WriteLogToFile($"[IACoreIPC] 辅助进程启动{(pipeReady ? "成功" : "失败(Pipe 未就绪)")},PID={_helperProcess?.Id}"); return pipeReady; } - catch (Exception ex) + catch { - LogHelper.WriteLogToFile($"[IACoreIPC] 启动辅助进程失败: {ex.Message}", LogHelper.LogType.Error); _available = false; return false; } @@ -161,7 +125,6 @@ namespace Ink_Canvas.Helpers using (var probe = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut)) { probe.Connect(200); - // 连接成功后立即断开,下次 Recognize 会重新连接 return true; } } @@ -183,7 +146,6 @@ namespace Ink_Canvas.Helpers using (var writer = new BinaryWriter(client, System.Text.Encoding.UTF8, leaveOpen: true)) using (var reader = new BinaryReader(client, System.Text.Encoding.UTF8, leaveOpen: true)) { - // 序列化请求 writer.Write(CmdRecognize); writer.Write(strokes.Count); foreach (var stroke in strokes) @@ -199,7 +161,6 @@ namespace Ink_Canvas.Helpers } writer.Flush(); - // 读取响应 bool success = reader.ReadBoolean(); string shape = reader.ReadString(); float cx = reader.ReadSingle(); @@ -220,7 +181,6 @@ namespace Ink_Canvas.Helpers if (!success || string.IsNullOrEmpty(shape)) return InkShapeRecognitionResult.Empty; - // 根据下标还原参与识别的笔画子集 var recognized = new StrokeCollection(); foreach (int idx in indices) if (idx >= 0 && idx < strokes.Count) @@ -240,16 +200,12 @@ namespace Ink_Canvas.Helpers private void EnsureHelperAlive() { if (!IsAvailable) - { - LogHelper.WriteLogToFile("[IACoreIPC] 辅助进程不可用,尝试重启...", LogHelper.LogType.Warning); LaunchHelper(); - } } private void OnHelperExited(object sender, EventArgs e) { _available = false; - LogHelper.WriteLogToFile("[IACoreIPC] 辅助进程意外退出", LogHelper.LogType.Warning); } private void KillHelper() @@ -257,12 +213,10 @@ namespace Ink_Canvas.Helpers if (_helperProcess == null) return; try { - // 先解除事件订阅,避免主动 Kill 时触发 OnHelperExited 误报 try { _helperProcess.Exited -= OnHelperExited; } catch { } if (!_helperProcess.HasExited) { - // 发送优雅关闭命令 try { using (var client = new NamedPipeClientStream(".", PipeName, PipeDirection.InOut)) @@ -272,7 +226,7 @@ namespace Ink_Canvas.Helpers w.Write(CmdShutdown); } } - catch { /* 忽略,下面直接 Kill */ } + catch { } if (!_helperProcess.WaitForExit(800)) _helperProcess.Kill(); @@ -294,7 +248,6 @@ namespace Ink_Canvas.Helpers KillHelper(); } - // ── 协议常量(与 IACoreHelper/IpcProtocol.cs 保持一致) ───────────── private const int IpcTimeoutMs = 5000; private const byte CmdRecognize = 0x01; private const byte CmdShutdown = 0xFF; diff --git a/Ink Canvas/Properties/Strings.resx b/Ink Canvas/Properties/Strings.resx index 594af26d..03da96e4 100644 --- a/Ink Canvas/Properties/Strings.resx +++ b/Ink Canvas/Properties/Strings.resx @@ -589,7 +589,7 @@ 识别引擎 - 自动:64 位进程使用 WinRT(Windows 10+),32 位使用 IACore。可强制指定 IACore 或 WinRT。 + 自动:在 Windows 10+ 使用 WinRT,否则使用 IACore。可强制指定 IACore 或 WinRT。IACore 通过 IPC 辅助进程运行,在 32/64 位主进程下均可用。 自动 diff --git a/InkCanvasForClass.IACoreHelper/Program.cs b/InkCanvasForClass.IACoreHelper/Program.cs index 5b701235..640606f5 100644 --- a/InkCanvasForClass.IACoreHelper/Program.cs +++ b/InkCanvasForClass.IACoreHelper/Program.cs @@ -2,7 +2,6 @@ using System; using System.IO; using System.IO.Pipes; using System.Linq; -using System.Windows; using System.Windows.Ink; using System.Windows.Input; @@ -10,29 +9,16 @@ namespace InkCanvasForClass.IACoreHelper { internal static class Program { - private static readonly string LogPath = Path.Combine( - AppDomain.CurrentDomain.BaseDirectory, "IACoreHelper.log"); - - private static void Log(string msg) - { - try { File.AppendAllText(LogPath, $"{DateTime.Now:HH:mm:ss.fff} {msg}{Environment.NewLine}"); } - catch { } - } - [STAThread] static void Main(string[] args) { - Log($"=== Helper started, args=[{string.Join(",", args)}], cwd={Environment.CurrentDirectory}, baseDir={AppDomain.CurrentDomain.BaseDirectory} ==="); - if (args.Length < 1 || !int.TryParse(args[0], out int parentPid)) { Console.Error.WriteLine("Usage: IACoreHelper.exe "); - Log("Missing parentPid argument, exiting"); return; } string pipeName = string.Format(IpcConstants.PipeName, parentPid); - Log($"Pipe name: {pipeName}"); try { @@ -40,7 +26,6 @@ namespace InkCanvasForClass.IACoreHelper } catch (Exception ex) { - Log($"FATAL: {ex}"); Console.Error.WriteLine("IACoreHelper fatal: " + ex.Message); } } @@ -82,7 +67,6 @@ namespace InkCanvasForClass.IACoreHelper Console.Error.WriteLine("IACoreHelper pipe error: " + ex.Message); } } - // 每次连接后重新监听,支持多次调用 } } @@ -90,19 +74,14 @@ namespace InkCanvasForClass.IACoreHelper { try { - Log($"HandleRecognize: strokes={request.Strokes?.Length ?? 0}"); var strokes = BuildStrokeCollection(request); - Log($"Built StrokeCollection: count={strokes.Count}"); if (strokes.Count == 0) return new RecognizeResponse { Success = false, ShapeName = string.Empty }; - var result = RecognizeCore(strokes); - Log($"RecognizeCore result: success={result.Success}, shape={result.ShapeName}"); - return result; + return RecognizeCore(strokes); } catch (Exception ex) { - Log($"HandleRecognize EXCEPTION: {ex}"); Console.Error.WriteLine("IACoreHelper recognize error: " + ex.Message); return new RecognizeResponse { Success = false, ShapeName = string.Empty }; } @@ -189,7 +168,6 @@ namespace InkCanvasForClass.IACoreHelper if (hot != null) for (int i = 0; i < hot.Count; i++) { hotX[i] = (float)hot[i].X; hotY[i] = (float)hot[i].Y; } - // 计算参与识别的笔画在原始集合中的下标 var participatingStrokes = analysisAlternate.Strokes; int[] strokeIndices = new int[participatingStrokes?.Count ?? 0]; if (participatingStrokes != null)