electron launcher
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

648 lines
20 KiB

4 years ago
  1. // Modules to control application life and create native browser window
  2. const {app, BrowserWindow,crashReporter} = require('electron')
  3. const ipc = require('electron').ipcMain
  4. // Keep a global reference of the window object, if you don't, the window will
  5. // be closed automatically when the JavaScript object is garbage collected.
  6. const electron = require('electron')
  7. console.log("进入程序时间:",new Date().getTime())
  8. const Menu = electron.Menu
  9. const Tray = electron.Tray
  10. const path =require('path')
  11. let showWindowFlg = null
  12. process.argv.forEach(e=>{
  13. showWindowFlg = e
  14. console.log(e,showWindowFlg)
  15. })
  16. //托盘对象
  17. var appTray =null
  18. let mainWindow = null,kjMain = null,miniWindow =null,kjMain_tray =null
  19. let dateStart,dateEnd,showMulWin,gotTheLock=false
  20. /**
  21. * 读取配置文件
  22. * @type {boolean}
  23. */
  24. const fs = require("fs")
  25. const newFile_path = path.join(__dirname,'./config/config.json').replace(/\\/g,"\/")
  26. fs.exists(newFile_path,function (exists) {
  27. console.log(exists ? "文件存在" : "文件不存在")
  28. if (exists) {
  29. console.log("配置文件",newFile_path)
  30. }
  31. })
  32. let temp =fs.readFileSync(newFile_path)
  33. showMulWin = JSON.parse(temp).showMulWin
  34. console.log("showMulWin的值",showMulWin)
  35. //系统托盘邮件菜单
  36. let trayMenuTemplate = [
  37. {
  38. label: '刷新界面',
  39. click: function () {
  40. // 如果kjMain 不为空则先关闭该窗口
  41. if (kjMain !=null){
  42. kjMain.restore()
  43. kjMain.reload()
  44. }
  45. // mainWindow.reload()
  46. },//打开相应的页面
  47. type: 'radio'
  48. },
  49. {
  50. label: '打开调试窗口',
  51. click: function () {
  52. //console.log(kjMain.devToolsWebContents)
  53. if (kjMain !=null){
  54. // kjMain.webContents.openDevTools()
  55. kjMain.webContents.send('openDevTools',"open devTools")
  56. }
  57. else {
  58. initWin()
  59. kjMain.webContents.openDevTools()
  60. }
  61. },
  62. type: 'radio',
  63. },
  64. ,
  65. {
  66. label: '显示消息通知',
  67. click: function () {
  68. if(mainWindow !=null ){
  69. if (kjMain!=null){
  70. kjMain.minimize()
  71. // kjMain.hide() //linux下需要去掉
  72. }
  73. mainWindow.show()
  74. mainWindow.restore()
  75. mainWindow.setSkipTaskbar(true)
  76. }
  77. },
  78. type: 'radio'
  79. },
  80. {
  81. label: '最小化消息通知',
  82. click: function () {
  83. // mainWindow.close()
  84. mainWindow.hide()
  85. console.log("hide!!!")
  86. },
  87. type:'radio',
  88. },
  89. {
  90. label: '打开双屏模式',
  91. click: function () {
  92. if (kjMain_tray==null){
  93. console.log("新建browser")
  94. initWinKj()
  95. } else {
  96. console.log("已经存在新框架")
  97. kjMain_tray.restore()
  98. kjMain_tray.show()
  99. }
  100. },
  101. type:'radio',
  102. },
  103. {
  104. label: '退出框架系统',
  105. click: function () {
  106. if (kjMain !=null){
  107. console.log("主进程向preload发送进程")
  108. kjMain.webContents.send('dispatchCloseButton',"回掉退出按钮")
  109. }
  110. if (setDialog !=null){
  111. setDialog.close()
  112. }
  113. if (kjMain_tray!=null) {
  114. kjMain_tray.close()
  115. }
  116. console.log("成功退出!!!")
  117. if (kjMain!=null){
  118. kjMain.hide()
  119. setTimeout(()=>{
  120. kjMain.close()
  121. },500)
  122. }
  123. mainWindow.close()
  124. },
  125. // icon: path.join(path.join(__dirname,'tray'),'tb2.png')
  126. type:'radio',
  127. }
  128. ]
  129. function createWindow (){
  130. console.log("chu shi hua yingyong")
  131. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize
  132. mainWindow = new BrowserWindow({
  133. width: 469,
  134. height: 780,
  135. //将页面显示在桌面右下角,x=屏幕宽度-窗口宽度 ,y=屏幕高度-窗口高度
  136. /* x: screenWidth-widthx,
  137. y: screenHeight-heighty,*/
  138. x: areaSize.width-469,
  139. y: areaSize.height-780,
  140. fullscreen:false,
  141. webPreferences: {
  142. nodeIntegration: true, // 这里是否需要node.js的支持,如果true可能和空中突击旅框架中用到的require冲突,需要设置成false。
  143. webSecurity: true
  144. },
  145. icon : path.join(path.join(__dirname,'tray'),'tb2.png'),
  146. transparent:true,
  147. hasShadow:false,
  148. alwaysOnTop:false,
  149. frame:false,
  150. })
  151. if (mainWindow !=null) {
  152. mainWindow.minimize()
  153. mainWindow.hide()
  154. }
  155. mainWindow.loadFile('msgList.html')
  156. //系统托盘目录
  157. let trayIcon =path.join(__dirname,'tray')
  158. appTray = new Tray(path.join(trayIcon,'tb2.png'))
  159. const contextMenu = Menu.buildFromTemplate(trayMenuTemplate)
  160. appTray.setToolTip('指挥信息系统') //修改托盘的名字,如果换成统行需要修改
  161. appTray.setContextMenu(contextMenu)
  162. //图片功能闪烁的实现
  163. // var count = 0
  164. // timer = null
  165. // timer = setInterval(function () {
  166. // count ++
  167. // if (count % 2 ==0){
  168. // appTray.setImage(path.join(trayIcon,'empty.png'))
  169. // }else {
  170. // appTray.setImage(path.join(trayIcon,'tb2.png'))
  171. // }
  172. // },500)
  173. appTray.on('click',() => { //在linux平台下没有此功能
  174. if (kjMain !=null){
  175. mainWindow.isVisible() ?
  176. (mainWindow.hide(),kjMain.show()) : (mainWindow.show(),kjMain.hide())
  177. } else {
  178. mainWindow.isVisible() ?
  179. (mainWindow.hide()) : (mainWindow.show())
  180. }
  181. // mainWindow.isVisible() ?
  182. // (mainWindow.setSkipTaskbar(false),kjMain.maximize()) : (mainWindow.setSkipTaskbar(true),kjMain.maximize())
  183. // mainWindow.show()
  184. console.log("dian ji shijian ")
  185. // timer.Enable= false
  186. })
  187. mainWindow.webContents.on('dom-ready',()=>{
  188. console.log("主进程开始时间:",new Date().getTime())
  189. })
  190. // mainWindow.on('show', () => {
  191. // appTray.setHighlightMode('always')
  192. // })
  193. //
  194. // mainWindow.on('hide', () => {
  195. // appTray.setHighlightMode('never')
  196. // })
  197. }
  198. function createMiniWindow (){
  199. console.log("chu shi hua mini")
  200. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize
  201. mainWindow = new BrowserWindow({
  202. width: 469,
  203. height: 780,
  204. //将页面显示在桌面右下角,x=屏幕宽度-窗口宽度 ,y=屏幕高度-窗口高度
  205. /* x: screenWidth-widthx,
  206. y: screenHeight-heighty,*/
  207. x: areaSize.width-469,
  208. y: areaSize.height-780,
  209. fullscreen:false,
  210. webPreferences: {
  211. nodeIntegration: true, // 这里是否需要node.js的支持,如果true可能和空中突击旅框架中用到的require冲突,需要设置成false。
  212. webSecurity: true
  213. },
  214. icon : path.join(path.join(__dirname,'tray'),'tb2.png'),
  215. transparent:true,
  216. hasShadow:false,
  217. alwaysOnTop:false,
  218. frame:false,
  219. })
  220. if (mainWindow !=null) {
  221. mainWindow.minimize()
  222. mainWindow.hide()
  223. }
  224. mainWindow.loadFile('msgMiniList.html')
  225. //系统托盘目录
  226. let trayIcon =path.join(__dirname,'tray')
  227. appTray = new Tray(path.join(trayIcon,'tb2.png'))
  228. const contextMenu = Menu.buildFromTemplate(trayMenuTemplate)
  229. appTray.setToolTip('指挥信息系统') //修改托盘的名字,如果换成统行需要修改
  230. appTray.setContextMenu(contextMenu)
  231. appTray.on('click',() => { //在linux平台下没有此功能
  232. if (kjMain !=null){
  233. mainWindow.isVisible() ?
  234. (mainWindow.hide(),kjMain.show()) : (mainWindow.show(),kjMain.hide())
  235. } else {
  236. mainWindow.isVisible() ?
  237. (mainWindow.hide()) : (mainWindow.show())
  238. }
  239. console.log("dian ji shijian ")
  240. // timer.Enable= false
  241. })
  242. mainWindow.minimize()
  243. mainWindow.hide()
  244. mainWindow.on('show', () => {
  245. appTray.setHighlightMode('always')
  246. })
  247. mainWindow.on('hide', () => {
  248. appTray.setHighlightMode('never')
  249. })
  250. }
  251. //初始化时开启此窗口
  252. function initWin(){
  253. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize
  254. //window平台时使用mainWindow.hide(),银河麒麟平台时使用mainWindow.minimize()
  255. if (mainWindow !=null) {
  256. mainWindow.minimize()
  257. mainWindow.hide()
  258. }
  259. kjMain = new BrowserWindow({
  260. width: areaSize.width,
  261. height: areaSize.height,
  262. // width:1129,
  263. // height:635,
  264. fullscreen:true,
  265. offScreen:false,
  266. webPreferences: {
  267. nodeIntegration: true, // 这里是否需要node.js的支持,如果true可能和空中突击旅框架中用到的require冲突,所以要设置成false。
  268. webviewTag:true,
  269. webSecurity:false //跨域策略
  270. },
  271. backgroundColor:'#80FFFFFF',
  272. frame:false,
  273. icon : path.join(path.join(__dirname,'tray'),'tb2.png'),
  274. //show: false
  275. })
  276. // kjMain.hide()
  277. kjMain.loadFile('index7.html')
  278. // /**
  279. // * 清除缓存
  280. // * @type {Electron.Session}
  281. // */
  282. // const ses=kjMain.webContents.session
  283. // ses.clearStorageData()
  284. kjMain.on('closed', function () {
  285. // Dereference the window object, usually you would store windows
  286. // in an array if your app supports multi windows, this is the time
  287. // when you should delete the corresponding element.
  288. console.log("tui chu kjMain")
  289. // mainWindow.close()
  290. kjMain = null
  291. })
  292. kjMain.webContents.on('did-start-loading',()=>{
  293. console.log("kai shi jiazai xin jiemian",new Date().getTime())
  294. })
  295. kjMain.webContents.on('dom-ready',()=>{
  296. console.log("dom ready ..",new Date().getTime())
  297. })
  298. kjMain.webContents.on('did-stop-loading',()=>{
  299. dateEnd =new Date().getTime()
  300. console.log("wancheng xin jiemian jiazai",dateEnd,dateStart)
  301. })
  302. mainWindow.webContents.on('new-window',()=>{
  303. console.log("new-window...",new Date().getTime())
  304. })
  305. }
  306. // This method will be called when Electron has finished
  307. // initialization and is ready to create browser windows.
  308. // Some APIs can only be used after this event occurs.
  309. //新加载界面
  310. function initWinKj(){
  311. let areaSize = require('electron').screen.getPrimaryDisplay().workAreaSize
  312. kjMain_tray = new BrowserWindow({
  313. width: areaSize.width,
  314. height: areaSize.height,
  315. // width:1129,
  316. // height:635,
  317. fullscreen:false,
  318. offScreen:false,
  319. webPreferences: {
  320. nodeIntegration: true, // 这里是否需要node.js的支持,如果true可能和空中突击旅框架中用到的require冲突,所以要设置成false。
  321. webviewTag:true,
  322. webSecurity:false //跨域策略
  323. },
  324. backgroundColor:'#80FFFFFF',
  325. frame:true,
  326. icon : path.join(path.join(__dirname,'tray'),'tb2.png'),
  327. //show: false
  328. })
  329. // kjMain.hide()
  330. kjMain_tray.loadFile('index_tray.html')
  331. kjMain_tray.on("maximize",()=>{
  332. kjMain_tray.setMenuBarVisibility(false)
  333. kjMain_tray.setFullScreen(true)
  334. })
  335. //登陆界面最小化
  336. kjMain_tray.on('window-min-tray',()=>{
  337. if (kjMain_tray!=null){
  338. kjMain_tray.minimize()
  339. kjMain_tray.hide()
  340. }
  341. console.log("最小化框架kjmain_tray")
  342. })
  343. kjMain_tray.on('closed', function () {
  344. // Dereference the window object, usually you would store windows
  345. // in an array if your app supports multi windows, this is the time
  346. // when you should delete the corresponding element.
  347. console.log("tui chu kjMain_tray")
  348. // mainWindow.close()
  349. kjMain_tray = null
  350. })
  351. }
  352. app.commandLine.appendSwitch("--disable-http-cache") // 功能类似于Chrome 调试下“disable cache”禁止缓存的功能。必须在app.on('ready')前使用
  353. //设置当个实例的例子
  354. gotTheLock = app.requestSingleInstanceLock()
  355. console.log("huo qu gotTheLock de value",gotTheLock)
  356. console.log(showMulWin,"111")
  357. if (showMulWin =="true"){
  358. gotTheLock = showMulWin
  359. console.log("she zhi gotTheLock de value",gotTheLock)
  360. }
  361. if (!gotTheLock) {
  362. console.log("app的信息",app)
  363. app.quit()
  364. } else {
  365. app.on('second-instance',(event,commandLine,workingDirectory)=>{
  366. //当运行到第二个实例时,将会聚焦到myWindow这个窗口
  367. if (mainWindow){
  368. if (kjMain == null){
  369. initWin()
  370. kjMain.focus()
  371. kjMain.restore()
  372. //kjMain.maximize()
  373. }else if (kjMain.isMinimized!=undefined && kjMain.isMinimized()){ //如果最小化,就将最小化恢复
  374. kjMain.focus()
  375. kjMain.restore()
  376. }else {
  377. kjMain.focus()
  378. kjMain.restore()
  379. kjMain.maximize()
  380. }
  381. //else if (kjMain == null){
  382. // initWin()
  383. //kjMain.maximize()
  384. // }
  385. }
  386. console.log("23232323")
  387. })
  388. if (showWindowFlg == 'tray'){
  389. app.on('ready',createMiniWindow)
  390. } else {
  391. app.on('ready', createWindow)
  392. }
  393. // app.on('ready', () =>{
  394. // initWin();
  395. // })
  396. }
  397. app.commandLine.appendSwitch('ignore-gpu-blacklist') //解决飞腾麒麟服务器显示3D地图报cesium.js的问题
  398. // Quit when all windows are closed.
  399. app.on('window-all-closed', function () {
  400. // On macOS it is common for applications and their menu bar
  401. // to stay active until the user quits explicitly with Cmd + Q
  402. if (process.platform !== 'darwin') app.quit()
  403. })
  404. app.on('activate', function () {
  405. // On macOS it's common to re-create a window in the app when the
  406. // dock icon is clicked and there are no other windows open.
  407. if (mainWindow === null) createWindow()
  408. })
  409. // app.setPath("temp","app/launhcer/custom")
  410. //crashReporter.start()
  411. // //登陆界面最大化
  412. ipc.on('window-max',function (){
  413. if (mainWindow.isMaximized()){
  414. mainWindow.restore()
  415. } else {
  416. mainWindow.maximize()
  417. }
  418. })
  419. // const areaSize1 = require('electron').screen.getPrimaryDisplay().workAreaSize
  420. global.sharedObject ={
  421. setMsgArr : [],
  422. someProperty : 'new value',
  423. dialogNum : 0
  424. } //渲染进程间共享数据
  425. //消息对话弹框
  426. let dialogWin = []
  427. ipc.on('msgLatest',(event,arg,num)=> {
  428. //console.log("mainwindow的状态",mainWindow.isMaximized(),mainWindow.isMaximized(),mainWindow.isVisible(),"kjMain的状态",kjMain.isVisible(),kjMain.isMaximized(),kjMain.isMinimized())
  429. if ( !mainWindow.isVisible()&&kjMain.isMinimized()||!mainWindow.isVisible()&&!kjMain.isVisible()){
  430. let areaSize1 = require('electron').screen.getPrimaryDisplay().workAreaSize
  431. let y_height = areaSize1.height
  432. // let y_height = y_height+3
  433. dialogWin[num] = new BrowserWindow({
  434. width: 460 ,
  435. height: 360,
  436. // fullscreen:true,
  437. x: areaSize1.width-460,
  438. y: y_height-360-3*num,
  439. webPreferences: {
  440. nodeIntegration: true // 这里是否需要node.js的支持,如果true可能和空中突击旅框架中用到的require冲突,所以要设置成false。
  441. },
  442. frame:false,
  443. icon : path.join(path.join(__dirname,'tray'),'tb2.png'),
  444. })
  445. dialogWin[num].loadFile('msg_diag.html')
  446. dialogWin[num].setAlwaysOnTop(true)
  447. console.log(arg,num)
  448. }
  449. })
  450. //消息设置窗口
  451. let setDialog = null
  452. ipc.on('openSetDialog',(event,arg)=>{
  453. if(setDialog !=null){
  454. setDialog.restore()
  455. }
  456. else {
  457. console.log(arg)
  458. let areaSize1 = require('electron').screen.getPrimaryDisplay().workAreaSize
  459. // let y_height = y_height+3
  460. setDialog = new BrowserWindow({
  461. width: 460 ,
  462. height: 360,
  463. // fullscreen:true,
  464. x: areaSize1.width-1200,
  465. y: areaSize1.height-500,
  466. webPreferences: {
  467. nodeIntegration: true // 这里是否需要node.js的支持,如果true可能和空中突击旅框架中用到的require冲突,所以要设置成false。
  468. },
  469. frame:false,
  470. icon : path.join(path.join(__dirname,'tray'),'tb2.png'),
  471. })
  472. setDialog.loadFile('setDialog.html')
  473. }
  474. })
  475. // 启动时初始化软件框架
  476. ipc.on('rjkj',()=> {
  477. console.log("chu shi hua shi dakai")
  478. dateStart = new Date().getTime()
  479. initWin()
  480. })
  481. //发送通信机制来显示框架
  482. ipc.on('displayKJ',()=> {
  483. if (kjMain != null) {
  484. mainWindow.minimize()
  485. console.log("da kai renjia kuagnjia",kjMain.isMinimized(),!kjMain.isVisible)
  486. if (kjMain.isMinimized() || kjMain.isVisible){ //如果最小化,就将最小化恢复
  487. kjMain.focus()
  488. kjMain.restore()
  489. kjMain.show()
  490. //kjMain.maximize()
  491. }else {
  492. kjMain.focus()
  493. kjMain.restore()
  494. //kjMain.maximize()
  495. console.log("启动人机框架")
  496. }
  497. //kjMain.maximize()
  498. }else {
  499. console.log("diaoyong kj")
  500. initWin()
  501. }
  502. })
  503. console.log("完成程序时间:",new Date().getTime())
  504. // 获取最新消息时弹出消息通知
  505. ipc.on('displayNotice',()=> {
  506. console.log("get latest data")
  507. console.log(mainWindow.isVisible())
  508. if (kjMain !=null) {
  509. console.log("zhi xing 1",kjMain.isVisible(),kjMain.isMinimized())
  510. if (!(mainWindow.isVisible()) && kjMain.isMinimized()){
  511. console.log("only show message 1 ")
  512. mainWindow.show();
  513. }
  514. }
  515. else {
  516. console.log("zhi xing 2")
  517. if (!(mainWindow.isVisible()) ){
  518. console.log("only show message 2")
  519. mainWindow.show();
  520. }
  521. }
  522. })
  523. //登陆界面最小化
  524. ipc.on('window-min',()=>{
  525. if (kjMain != null) {
  526. console.log("kjmain的Minized的值:",kjMain.isMinimized())
  527. kjMain.minimize()
  528. }
  529. console.log("最小化kjMain")
  530. })
  531. //登陆界面最小化
  532. ipc.on('window-min-tray',()=>{
  533. if (kjMain_tray != null) {
  534. console.log("kjmain_tray的minisized值是:",kjMain_tray.isMinimized())
  535. kjMain_tray.minimize()
  536. }
  537. console.log("最小化框架kjmain_tray")
  538. })
  539. //登陆界面最关闭
  540. ipc.on('window-close',()=>{
  541. console.log("tuichu kj")
  542. if (kjMain !=null){
  543. kjMain.close()
  544. }
  545. if (kjMain_tray!=null){
  546. kjMain_tray.close()
  547. }
  548. if (mainWindow !=null){
  549. mainWindow.close()
  550. }else {
  551. mainWindow.close()
  552. }
  553. })
  554. //登陆界面最关闭
  555. ipc.on('window-close-tray',()=>{
  556. console.log("tuichu kj")
  557. if (kjMain!=null){
  558. kjMain.close()
  559. }
  560. if (kjMain_tray!=null){
  561. kjMain_tray.close()
  562. }
  563. if (mainWindow !=null){
  564. mainWindow.close()
  565. }else {
  566. mainWindow.close()
  567. }
  568. })
  569. //关闭弹窗提醒窗口
  570. ipc.on('openDialog',(event,arg)=> {
  571. const {dialog ,shell ,nativeImage} =require('electron')
  572. dialog.showMessageBox({
  573. type: "info",
  574. title: "消息",
  575. message : arg.text,
  576. buttons : ["确定","取消"],
  577. icon:nativeImage.createFromPath("./tray/close_button.png"),
  578. })
  579. })
  580. ipc.on('closeDialog',(event,arg) =>{
  581. // dialogWin="dialogWin"+arg
  582. console.log("guan bi tanchuan",arg)
  583. if (dialogWin[arg] !=null){
  584. dialogWin[arg].close()
  585. }
  586. })
  587. ipc.on('closeSetDialog',(event,arg) =>{
  588. setDialog.close()
  589. setDialog = null
  590. })
  591. // In this file you can include the rest of your app's specific main process
  592. // code. You can also put them in separate files and require them here.