11import path , { join , resolve } from 'path' ;
22import { Conf , useConf } from 'electron-conf/main' ;
3-
3+ import log from 'electron-log' ;
44import { app , BrowserWindow , ipcMain , session , shell } from 'electron' ;
55
66import { execFile } from 'child_process' ;
@@ -22,9 +22,13 @@ let defaults = {
2222 language : 'en'
2323 }
2424} ;
25+
2526let mainWindow : BrowserWindow | null = null ;
2627
27- const platform = process . platform === 'win32' ? 'windows' : process . platform === 'darwin' ? 'macos' : 'linux' ;
28+ let openMainWindow : boolean = true ;
29+
30+ const platform =
31+ process . platform === 'win32' ? 'windows' : process . platform === 'darwin' ? 'macos' : 'linux' ;
2832const configFilePath = path . join ( app . getPath ( 'userData' ) , 'config.json' ) ;
2933
3034if ( ! existsSync ( configFilePath ) ) {
@@ -56,21 +60,23 @@ const handleUrl = (url: string) => {
5660
5761 if ( token ) {
5862 const decodedTokenJson = Buffer . from ( token , 'base64' ) . toString ( 'utf-8' ) ;
59-
6063 try {
6164 const decodedToken = JSON . parse ( decodedTokenJson ) ;
6265 if ( 'bearer_token' in decodedToken ) {
66+ openMainWindow = true ;
6367 mainWindow ?. webContents . send ( 'set-token' , decodedToken . bearer_token ) ;
6468 } else {
69+ openMainWindow = false ;
6570 handleClientPullUp ( url ) ;
6671 }
72+ log . info ( 'handleUrl:' , openMainWindow ) ;
6773 } catch ( error ) {
68- console . error ( 'Failed to parse decoded token:' , error ) ;
74+ log . error ( 'Failed to parse decoded token:' , error ) ;
6975 }
7076 }
7177} ;
7278
73- const handleArgv = ( argv : any ) => {
79+ const handleArgv = ( argv : string [ ] ) => {
7480 const offset = app . isPackaged ? 1 : 2 ;
7581 const url = argv . find ( ( arg , i ) => i >= offset && arg . startsWith ( 'jms' ) ) ;
7682 if ( url ) handleUrl ( url ) ;
@@ -97,7 +103,7 @@ const handleClientPullUp = (url: string) => {
97103 } else {
98104 subPath += '/windows' ;
99105 }
100- let exeFilePath = path . join ( subPath , 'JumpServerClient' ) ;
106+ const exeFilePath = path . join ( subPath , 'JumpServerClient' ) ;
101107 execFile ( exeFilePath , [ url ] , error => {
102108 if ( error ) {
103109 console . log ( error ) ;
@@ -107,7 +113,8 @@ const handleClientPullUp = (url: string) => {
107113} ;
108114
109115const createWindow = async ( ) : Promise < void > => {
110- const windowBounds = ( conf . get ( 'windowBounds' ) as { width : number ; height : number } ) || defaults . windowBounds ;
116+ const windowBounds =
117+ ( conf . get ( 'windowBounds' ) as { width : number ; height : number } ) || defaults . windowBounds ;
111118
112119 mainWindow = new BrowserWindow ( {
113120 width : windowBounds . width ,
@@ -132,7 +139,11 @@ const createWindow = async (): Promise<void> => {
132139 } ) ;
133140
134141 mainWindow . webContents . setWindowOpenHandler ( details => {
135- shell . openExternal ( details . url ) ;
142+ try {
143+ shell . openExternal ( details . url ) ;
144+ } catch ( err ) {
145+ log . error ( 'Failed to open external URL:' , err ) ;
146+ }
136147 return { action : 'deny' } ;
137148 } ) ;
138149
@@ -179,6 +190,24 @@ const createWindow = async (): Promise<void> => {
179190 }
180191} ;
181192
193+ // @ts -ignore
194+ app . on ( 'second-instance' , ( _event : Event , argv : string [ ] ) => {
195+ log . info ( 'second-instance' ) ;
196+ if ( process . platform === 'win32' || process . platform === 'linux' ) {
197+ handleArgv ( argv ) ;
198+ }
199+ if ( mainWindow && openMainWindow ) {
200+ if ( mainWindow . isMinimized ( ) ) mainWindow . restore ( ) ;
201+ mainWindow . focus ( ) ;
202+ }
203+ } ) ;
204+
205+ // @ts -ignore
206+ app . on ( 'open-url' , ( _event : Event , url : string ) => {
207+ log . info ( 'open-url' ) ;
208+ handleUrl ( url ) ;
209+ } ) ;
210+
182211! app . requestSingleInstanceLock ( ) ? app . quit ( ) : '' ;
183212
184213app . whenReady ( ) . then ( async ( ) => {
@@ -200,21 +229,25 @@ app.whenReady().then(async () => {
200229 conf . registerRendererListener ( ) ;
201230 useConf ( ) ;
202231
203- await createWindow ( ) ;
204232 setDefaultProtocol ( ) ;
205233
206- setTitleBar ( conf . get ( 'defaultSetting.theme' ) as string ) ;
207-
208- if ( process . platform === 'win32' ) {
234+ if ( process . platform === 'win32' || process . platform === 'linux' ) {
209235 handleArgv ( process . argv ) ;
210236 }
237+ log . info ( 'whenReady: ' , openMainWindow ) ;
238+ if ( openMainWindow ) {
239+ await createWindow ( ) ;
240+ setTitleBar ( conf . get ( 'defaultSetting.theme' ) as string ) ;
241+ } else {
242+ app . quit ( ) ;
243+ }
211244
212245 app . on ( 'activate' , function ( ) {
213- if ( BrowserWindow . getAllWindows ( ) . length === 0 ) createWindow ( ) ;
246+ if ( BrowserWindow . getAllWindows ( ) . length === 0 && openMainWindow ) createWindow ( ) ;
214247 } ) ;
215248
216249 if ( is . dev ) {
217- if ( process . platform === 'win32' ) {
250+ if ( process . platform === 'win32' || process . platform === 'linux' ) {
218251 process . on ( 'message' , data => {
219252 if ( data === 'graceful-exit' ) {
220253 app . quit ( ) ;
@@ -231,26 +264,7 @@ app.whenReady().then(async () => {
231264// 除外 macOS 外,关闭所有窗口时退出 app
232265app . on ( 'window-all-closed' , ( ) => {
233266 // mainWindow 可能已经被销毁,所以不要再尝试访问它
234- if ( process . platform !== 'darwin' ) {
235- app . quit ( ) ;
236- }
237- } ) ;
238-
239- // @ts -ignore
240- app . on ( 'second-instance' , ( _event : Event , argv : string ) => {
241- if ( process . platform === 'win32' ) {
242- handleArgv ( argv ) ;
243- }
244- if ( mainWindow ) {
245- if ( mainWindow . isMinimized ( ) ) mainWindow . restore ( ) ;
246- mainWindow . focus ( ) ;
247- }
248- } ) ;
249-
250- // 从 web 唤起 Client
251- // @ts -ignore
252- app . on ( 'open-url' , ( _event : Event , url : string ) => {
253- handleUrl ( url ) ;
267+ app . quit ( ) ;
254268} ) ;
255269
256270const setTitleBar = ( theme : string ) => {
0 commit comments