// ============================================================ // UmiOcrLauncher:Umi-OCR 本体进程启停(与 UmiOcrHost 拆分) // · 启动 = 静默启动安装目录里的主程序(--hide 官方参数,主窗口进托盘, // 后台提供 HTTP 服务 1224 端口) → 轮询端口就绪 // · 停止 = 只停由本程序启动的实例(官方 --quit 指令→超时 Kill),不碰用户自己开的 // · exe 路径 = 安装目录固定文件名(UmiOcrHost.ExePath),参数全部为官方常量,无用户输入 // ============================================================ using System; using System.Diagnostics; using System.IO; namespace 成套报价软件 { internal static class UmiOcrLauncher { /// Umi-OCR 官方启动参数:主窗口隐藏到托盘,后台提供 HTTP 服务。 private const string HideArg = "--hide"; /// Umi-OCR 官方退出参数:向已运行实例发优雅退出指令。 private const string QuitArg = "--quit"; /// 由本程序启动的实例(停止时只关它,不碰用户自己开的)。 private static Process _startedProc; /// 确保本体已安装且 HTTP 服务在线:未安装抛错引导下载;未运行则静默启动 /// (--hide 主窗口进托盘)并等端口就绪(≤15秒)。返回 false=已安装但启动超时(调用方提示)。 public static bool EnsureRunning() { if (!UmiOcrHost.IsInstalled) throw new Exception("尚未安装 Umi-OCR 本体。\r\n请到 OCR 设置窗口选择 Umi-OCR 引擎,点\"下载 OCR 本体\"。"); if (UmiOcrHost.IsHttpUp()) return true; string exe = UmiOcrHost.ExePath; // 安装目录固定文件名(InstallDir\Umi-OCR.exe) var psi = new ProcessStartInfo { FileName = exe, Arguments = HideArg, // Umi-OCR 官方常量参数 WorkingDirectory = Path.GetDirectoryName(exe), UseShellExecute = false, CreateNoWindow = true, WindowStyle = ProcessWindowStyle.Hidden }; _startedProc = Process.Start(psi); for (int i = 0; i < 30; i++) // 30 × 500ms = 最多 15 秒 { if (UmiOcrHost.IsHttpUp()) return true; System.Threading.Thread.Sleep(500); } return false; } /// 停止由本程序启动的实例(PdfViewerWindow 关闭时调用;用户自己开的不动)。 /// --hide 启动的窗口在托盘,CloseMainWindow 不可靠:先发官方 --quit 指令优雅退出,超时再 Kill。 public static void StopIfStartedByUs() { var p = _startedProc; _startedProc = null; if (p == null) return; try { if (!p.HasExited) { // 官方退出指令:向已运行实例发 --quit(依赖其 HTTP 通道) try { if (UmiOcrHost.IsInstalled) { string exe = UmiOcrHost.ExePath; // 安装目录固定文件名 var quit = new ProcessStartInfo { FileName = exe, Arguments = QuitArg, // Umi-OCR 官方常量参数 UseShellExecute = false, CreateNoWindow = true }; Process.Start(quit); } } catch { } if (!p.WaitForExit(3000)) p.Kill(); } } catch { } finally { try { p.Dispose(); } catch { } } } } }