using System; using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using DevExpress.XtraSplashScreen; using System.Threading; using System.Globalization; using DevExpress.UserSkins; using DevExpress.Skins; using DevExpress.LookAndFeel; using Lskj.Control; using Lskj.Control.Model; using Lskj.Main.Model; using Lskj.Util; using Xilium.CefGlue; using System.Reflection; using System.IO; using Lskj.Control.BrowserSetting; using Microsoft.Win32; 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); //private static readonly IntPtr DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 = new IntPtr(-4); /// /// 应用程序的主入口点。 /// [STAThread] static int Main(string[] args) { 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" }; } #region 浏览器处理类 /// /// 说明:浏览器处理类 /// 创建人:唐德馨 /// 创建日期:2022-1-26 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 internal sealed class DemoCefApp : CefApp { private CefRenderProcessHandler _renderProcessHandler = new BsRenderProcessHandler(); protected override void OnBeforeCommandLineProcessing(string processType, CefCommandLine commandLine) { //Console.WriteLine("OnBeforeCommandLineProcessing: {0} {1}", processType, commandLine); // TODO: currently on linux platform location of locales and pack files are determined // incorrectly (relative to main module instead of libcef.so module). // Once issue http://code.google.com/p/chromiumembedded/issues/detail?id=668 will be resolved // this code can be removed. Version currentVersion = Environment.OSVersion.Version; Version compareToVersion = new Version("6.2"); //if (CefRuntime.Platform == CefRuntimePlatform.Windows && currentVersion.CompareTo(compareToVersion) > 0) //{ //win8及其以下版本的系统 var path = new Uri(Assembly.GetEntryAssembly().CodeBase).LocalPath; path = Path.GetDirectoryName(path); commandLine.AppendSwitch("resources-dir-path", path); commandLine.AppendSwitch("locales-dir-path", Path.Combine(path, "locales")); commandLine.AppendSwitch("ignore-certificate-errors", "1"); commandLine.AppendSwitch("allow-running-insecure-content", "1"); //如果注册表中CefMultithreading不为1,并且根目录中不存在BrowserMultithreading.txt"文件,就是单线程模式 //只要有一个条件满足就是多线程模式 if (!BrowserMultithreading() && !File.Exists(PubUtil.AbsolutelyPath + "BrowserMultithreading.txt")) { commandLine.AppendSwitch("single-process", "1");//单线程模式,默认开启。(开启单线程模式后会影响浏览器的性能) } commandLine.AppendSwitch("no-proxy-server"); commandLine.AppendSwitch("ppapi-flash-version", "99.0.0.999"); commandLine.AppendSwitch("ppapi-flash-path", @"PepperFlash\pepflashplayer.dll"); //} } protected override CefRenderProcessHandler GetRenderProcessHandler() { return _renderProcessHandler; } } #endregion /// /// 说明:处理异常 /// 创建人:龚宇超 /// 创建日期:2017-11-22 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) { // 获取异常对象 Exception ex = e.Exception; MessageUtil.Show(ex); LogHelper.Instance.WriteError(e.Exception); } /// /// 说明:处理异常 /// 创建人:王一帆 /// 创建日期:2021-07-08 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// /// The source of the event. /// The instance containing the event data. private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { Console.WriteLine(e.ExceptionObject.ToString()); MessageUtil.Show(e.ExceptionObject.ToString()); } /// /// 说明:获取浏览器线程 /// 创建人:曹屹峰 /// 创建日期:2024-05-16 /// 修改人: /// 修改日期: /// 修改备注: /// 版本:1.0 /// private static bool BrowserMultithreading() { bool result = false; try { RegistryKey regKey = Registry.CurrentUser; RegistryKey erpKey = regKey.CreateSubKey("AA_LS_Erp V2.0"); erpKey.CreateSubKey("File"); RegistryKey subKey = regKey.OpenSubKey("AA_LS_Erp V2.0"); subKey = subKey.OpenSubKey("File", true); result = subKey.GetValue("CefMultithreading", "0") + "" == "1" || subKey.GetValue("CefMultithreading", "0") + "" == "True" ? true : false; return result; } catch (Exception ex) { } return false; } #region 注册自定义协议 private static void Register() { try { string exePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Lskj.CallWebLibrary.exe"); using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\lserp")) { key.SetValue("", "URL:LSERP Protocol"); key.SetValue("URL Protocol", ""); } using (var key = Registry.CurrentUser.CreateSubKey(@"Software\Classes\lserp\shell\open\command")) { key.SetValue("", $"\"{exePath}\" \"%1\""); } } catch (Exception ex) { } } private static void Unregister() { Registry.CurrentUser.DeleteSubKeyTree(@"Software\Classes\lserp", false); } #endregion //public static Form GetForm() //{ // Form X = new CEFdemo.Form1(); // return X; //} public class Messager : IMessageFilter { public bool PreFilterMessage(ref Message m) { //如果检测到有鼠标或则键盘的消息,则使计数为0..... if (m.Msg == 0x0200 || m.Msg == 0x0201 || m.Msg == 0x0204 || m.Msg == 0x0207) { Manager.isAwaitTime = 0; } if (m.Msg == 0x0100 && m.WParam != new IntPtr(0x0000001b) && Lskj.Model.ERPInfo.Instance.IsExecute) { return true; } return false; } } } }