WinApp.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. /**
  2. * app 模块
  3. */
  4. import { app, dialog, Menu, ipcMain, type MessageBoxSyncOptions } from "electron"
  5. import * as remote from "@electron/remote/main"
  6. import GlobalConfig from "./GlobalConfig"
  7. import { mainLog } from "../utils/logger"
  8. import WinMain from "./WinMain"
  9. import WinTray from "./WinTray"
  10. class WinApp {
  11. /** 初始化 app 配置 */
  12. private static initAppConfig() {
  13. // 禁用 硬件加速
  14. app.disableHardwareAcceleration()
  15. // 禁用 Chromium 沙盒
  16. app.commandLine.appendSwitch("no-sandbox")
  17. // 忽略证书相关错误
  18. app.commandLine.appendSwitch("ignore-certificate-errors")
  19. // 禁用 GPU
  20. // app.commandLine.appendSwitch("disable-gpu")
  21. // 禁用 GPU 沙盒
  22. // app.commandLine.appendSwitch("disable-gpu-sandbox")
  23. // 禁用 GPU 合成
  24. // app.commandLine.appendSwitch("disable-gpu-compositing")
  25. // 禁用 GPU 光栅化
  26. // app.commandLine.appendSwitch("disable-gpu-rasterization")
  27. // 禁用软件光栅化器
  28. // app.commandLine.appendSwitch("disable-software-rasterizer")
  29. // 禁用 HTTP 缓存
  30. app.commandLine.appendSwitch("disable-http-cache")
  31. // 禁用动画, 解决透明窗口打开闪烁问题
  32. app.commandLine.appendSwitch("wm-window-animations-disabled")
  33. }
  34. /** 是否获取应用单例锁 */
  35. static hasSingleLock() {
  36. return GlobalConfig.IS_DEV_MODE || app.requestSingleInstanceLock()
  37. }
  38. /** 启动应用 */
  39. static startApp() {
  40. if (!this.hasSingleLock()) {
  41. return this.exitApp("There are already instances running.")
  42. }
  43. // 禁用默认系统菜单
  44. Menu.setApplicationMenu(Menu.buildFromTemplate([]))
  45. // 初始化 remote
  46. remote.initialize()
  47. // 初始化 app 配置
  48. this.initAppConfig()
  49. // 挂载全局变量
  50. GlobalConfig.mountGlobalVariables()
  51. // 初始化完成
  52. app.whenReady().then(() => {
  53. this.ipcListening()
  54. WinMain.create()
  55. WinMain.ipcListening()
  56. WinTray.initTrayMenu()
  57. WinTray.create()
  58. WinTray.ipcListening()
  59. })
  60. // 运行第二个实例时
  61. app.on("second-instance", () => WinMain.show("second-instance"))
  62. // 所有的窗口都被关闭
  63. app.on("window-all-closed", () => {
  64. WinTray.destroy()
  65. this.exitApp()
  66. })
  67. // 程序退出之前
  68. app.on("before-quit", () => {
  69. mainLog.log("[before quit app] ")
  70. })
  71. // 程序退出
  72. app.on("quit", () => {
  73. mainLog.log("[app is quit] ")
  74. WinTray.destroy()
  75. app.releaseSingleInstanceLock()
  76. })
  77. }
  78. /** 重启应用 */
  79. static restartApp() {
  80. !GlobalConfig.IS_DEV_MODE && app.relaunch()
  81. app.exit(0)
  82. }
  83. /** 退出应用 */
  84. static exitApp(title?: string, content?: string) {
  85. mainLog.log("[exit-app] ", title || "", content || "")
  86. if (title && content) {
  87. const callback = () => {
  88. const opt: MessageBoxSyncOptions = {
  89. type: "warning",
  90. icon: GlobalConfig.getAppLogo(),
  91. noLink: true,
  92. title: title,
  93. message: `${content}`,
  94. buttons: ["确定"],
  95. cancelId: -1,
  96. defaultId: 0
  97. }
  98. dialog.showMessageBoxSync(opt)
  99. app.quit()
  100. }
  101. app.isReady() ? callback() : app.whenReady().then(callback)
  102. } else {
  103. app.quit()
  104. }
  105. }
  106. /** 监听相关事件 */
  107. static ipcListening() {
  108. // 重启
  109. ipcMain.on("restart_app", () => this.restartApp())
  110. }
  111. }
  112. export default WinApp