From 4d907cf1dd4f705acc242801ccf31ff43da3da9b Mon Sep 17 00:00:00 2001 From: SugarChes Date: Wed, 29 Jul 2026 13:58:20 +0800 Subject: [PATCH] refactor(startup): expose legacy process lifecycle --- .../Hosting/LegacyApplicationHost.cs | 87 +++++++- 插件库/Lskj.Main/Program.cs | 206 ++++++++++++++---- 2 files changed, 234 insertions(+), 59 deletions(-) diff --git a/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs b/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs index ddffb59..b920ab1 100644 --- a/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs +++ b/插件库/Lskj.Main/Hosting/LegacyApplicationHost.cs @@ -15,26 +15,91 @@ using Lskj.Util; namespace Lskj.Main.Hosting { + public sealed class LegacyProcessStartResult + { + internal LegacyProcessStartResult( + bool shouldRunApplication, + int exitCode) + { + ShouldRunApplication = shouldRunApplication; + ExitCode = exitCode; + } + + public bool ShouldRunApplication { get; private set; } + + public int ExitCode { get; private set; } + } + /// /// 为独立的新启动程序公开原 Ls_ERP 初始化和登录流程。 /// public static class LegacyApplicationHost { - public static void Run(string[] args, IExternalMainShell externalMainShell) - { - if (externalMainShell == null) - throw new ArgumentNullException("externalMainShell"); - if (Manager.ExternalMainShell != null) - throw new InvalidOperationException("旧程序已经由另一个外部主界面托管。"); + private static readonly object ProcessSync = new object(); + private static bool _mainProcessInitializationStarted; + private static bool _mainProcessInitialized; + private static bool _mainProcessShutdown; - Manager.ExternalMainShell = externalMainShell; - try + public static LegacyProcessStartResult PrepareProcess(string[] args) + { + int code = Program.PrepareProcess(args ?? new string[0]); + return new LegacyProcessStartResult(code == -1, code); + } + + public static void InitializeMainProcess(IExternalMainShell externalMainShell) + { + lock (ProcessSync) { - Program.RunFromExternalHost(args); + if (_mainProcessInitialized) + throw new InvalidOperationException( + "旧主进程运行时已经初始化。"); + if (_mainProcessShutdown) + throw new InvalidOperationException( + "旧主进程运行时已经关闭。"); + + _mainProcessInitializationStarted = true; + Manager.ExternalMainShell = externalMainShell; + try + { + Program.InitializeMainProcess(); + _mainProcessInitialized = true; + } + catch + { + try + { + Program.ShutdownMainProcess(); + } + finally + { + _mainProcessShutdown = true; + Manager.ExternalMainShell = null; + } + throw; + } } - finally + } + + public static void ShutdownMainProcess() + { + lock (ProcessSync) { - Manager.ExternalMainShell = null; + if (!_mainProcessInitializationStarted || + _mainProcessShutdown) + { + return; + } + + try + { + Program.ShutdownMainProcess(); + } + finally + { + _mainProcessInitialized = false; + _mainProcessShutdown = true; + Manager.ExternalMainShell = null; + } } } } diff --git a/插件库/Lskj.Main/Program.cs b/插件库/Lskj.Main/Program.cs index 6a1afc1..d1cefe9 100644 --- a/插件库/Lskj.Main/Program.cs +++ b/插件库/Lskj.Main/Program.cs @@ -21,11 +21,22 @@ using System.Resources; using System.Runtime.InteropServices; using System.Resources; using System.Diagnostics; +using Lskj.Main.Hosting; namespace Lskj.Main { static class Program { + private static CefMainArgs _mainArgs; + private static DemoCefApp _cefApp; + private static CefSettings _cefSettings; + private static Messager _messageFilter; + private static EventHandler _cefIdleHandler; + private static AboutDevCompanion _devCompanion; + private static bool _cefInitialized; + private static bool _mainProcessInitialized; + private static bool _mainProcessShutdown; + //[DllImport("user32.dll")] //private static extern bool SetProcessDpiAwarenessContext(IntPtr dpiContext); @@ -36,61 +47,160 @@ namespace Lskj.Main /// 应用程序的主入口点。 /// [STAThread] - static void Main(string[] args) + static int Main(string[] args) { - //SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); - CefRuntime.Load();//cef浏览器模块设置加载 - var mainArgs = new CefMainArgs(args); - var app = new DemoCefApp(); - var settings = new CefSettings + LegacyProcessStartResult processResult; + try + { + processResult = LegacyApplicationHost.PrepareProcess(args); + } + catch (Exception exception) + { + LogHelper.Instance.WriteError(exception); + return -1; + } + + if (!processResult.ShouldRunApplication) + return processResult.ExitCode; + + try + { + LegacyApplicationHost.InitializeMainProcess(null); + Manager.StartForm(); + return 0; + } + catch (Exception exception) + { + MessageUtil.Show(exception); + LogHelper.Instance.WriteError(exception); + return -1; + } + finally + { + LegacyApplicationHost.ShutdownMainProcess(); + } + } + + internal static int PrepareProcess(string[] args) + { + if (_mainArgs != null) + throw new InvalidOperationException("CEF 进程分流已经执行。"); + + CefRuntime.Load(); + _mainArgs = new CefMainArgs(args ?? new string[0]); + _cefApp = new DemoCefApp(); + _cefSettings = CreateCefSettings(); + int code = CefRuntime.ExecuteProcess( + _mainArgs, + _cefApp, + IntPtr.Zero); + Console.WriteLine( + "CefRuntime.ExecuteProcess() returns {0}", + code); + return code; + } + + internal static void InitializeMainProcess() + { + if (_mainProcessInitialized) + throw new InvalidOperationException("旧主进程环境已经初始化。"); + if (_mainProcessShutdown) + throw new InvalidOperationException("旧主进程环境已经关闭。"); + if (_mainArgs == null || _cefApp == null || _cefSettings == null) + throw new InvalidOperationException("尚未执行 CEF 进程分流。"); + + try + { + CefRuntime.Initialize( + _mainArgs, + _cefSettings, + _cefApp, + IntPtr.Zero); + _cefInitialized = true; + + Thread.CurrentThread.CurrentUICulture = + new CultureInfo("zh-CN"); + BonusSkins.Register(); + SkinManager.EnableFormSkins(); + + Application.SetUnhandledExceptionMode( + UnhandledExceptionMode.CatchException); + Application.EnableVisualStyles(); + Application.SetCompatibleTextRenderingDefault(false); + _messageFilter = new Messager(); + Application.AddMessageFilter(_messageFilter); + Application.ThreadException += Application_ThreadException; + AppDomain.CurrentDomain.UnhandledException += + CurrentDomain_UnhandledException; + + if (!_cefSettings.MultiThreadedMessageLoop) + { + _cefIdleHandler = delegate + { + CefRuntime.DoMessageLoopWork(); + }; + Application.Idle += _cefIdleHandler; + } + + _devCompanion = new AboutDevCompanion(1, false); + _devCompanion.Run(); + Register(); + _mainProcessInitialized = true; + } + catch + { + ShutdownMainProcess(); + throw; + } + } + + internal static void ShutdownMainProcess() + { + if (_mainProcessShutdown) + return; + _mainProcessShutdown = true; + + try + { + if (_cefIdleHandler != null) + { + Application.Idle -= _cefIdleHandler; + _cefIdleHandler = null; + } + Application.ThreadException -= Application_ThreadException; + AppDomain.CurrentDomain.UnhandledException -= + CurrentDomain_UnhandledException; + if (_messageFilter != null) + { + Application.RemoveMessageFilter(_messageFilter); + _messageFilter = null; + } + if (_devCompanion != null) + { + _devCompanion.Stop(); + _devCompanion = null; + } + } + finally + { + if (_cefInitialized) + { + CefRuntime.Shutdown(); + _cefInitialized = false; + } + _mainProcessInitialized = false; + } + } + + private static CefSettings CreateCefSettings() + { + return new CefSettings { MultiThreadedMessageLoop = true, LogSeverity = CefLogSeverity.Disable, LogFile = "CefGlue.log", Locale = "zh-CN" }; - try - { - var Code = CefRuntime.ExecuteProcess(mainArgs, app, IntPtr.Zero); - Console.WriteLine("CefRuntime.ExecuteProcess() returns {0}", Code); - } - catch (Exception ex) - { - } - CefRuntime.Initialize(mainArgs, settings, app, IntPtr.Zero); - try - { - // 汉化DevExpress界面 - Thread.CurrentThread.CurrentUICulture = new CultureInfo("zh-CN"); - // 设置皮肤 - BonusSkins.Register(); - SkinManager.EnableFormSkins(); - - //处理未捕获的异常 - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - Application.EnableVisualStyles(); - Application.SetCompatibleTextRenderingDefault(false); - Application.AddMessageFilter(new Messager()); - Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException); - AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException); - if (!settings.MultiThreadedMessageLoop)//消息循环 - { - Application.Idle += (sender, e) => { CefRuntime.DoMessageLoopWork(); }; - } - AboutDevCompanion DC = new AboutDevCompanion(1, false); - DC.Run(); - Register(); - // 启动程序 - Manager.StartForm(); - CefRuntime.Shutdown(); - DC.Stop(); - } - catch (Exception ex) - { - MessageUtil.Show(ex); - LogHelper.Instance.WriteError(ex); - } - } #region 浏览器处理类 ///