diff --git a/angular.json b/angular.json index f247748..b24aa89 100644 --- a/angular.json +++ b/angular.json @@ -34,7 +34,8 @@ "inlineStyleLanguage": "scss", "assets": [ "src/favicon.ico", - "src/assets" + "src/assets", + "src/splash.html" ], "scripts": [ "node_modules/jquery/dist/jquery.min.js", diff --git a/app/main.ts b/app/main.ts index 4d3a084..5b15e02 100644 --- a/app/main.ts +++ b/app/main.ts @@ -13,6 +13,11 @@ import { BatteryUtils, FileUtils, NetworkUtils } from './utils'; app.setName('Monero Daemon'); +if (process.platform === 'win32') +{ + app.setAppUserModelId(app.name); +} + let win: BrowserWindow | null = null; let isHidden: boolean = false; let isQuitting: boolean = false; @@ -121,7 +126,7 @@ function createTray(): Tray { return tray; } -function createWindow(): BrowserWindow { +async function createWindow(): Promise { const size = screen.getPrimaryDisplay().workAreaSize; tray = createTray(); @@ -167,7 +172,7 @@ function createWindow(): BrowserWindow { const url = new URL(path.join('file:', dirname, pathIndex)); console.log(`Main window url: ${url}`); - win.loadURL(url.href); + await win.loadURL(url.href); } win.on('close', (event) => { @@ -192,12 +197,8 @@ function createWindow(): BrowserWindow { return win; } -const createSplashWindow = async (): Promise => { - return undefined; - - if (os.platform() == 'win32' || AppMainProcess.isPortable) { - return undefined; - } +const createSplashWindow = async (): Promise => { + console.log("createSplashWindow()"); const window = new BrowserWindow({ width: 480, @@ -209,7 +210,12 @@ const createSplashWindow = async (): Promise => { icon: wdwIcon, minimizable: false, maximizable: false, - fullscreen: false + fullscreen: false, + fullscreenable: false, + movable: false, + resizable: false, + closable: true, + center: true }); // Path when running electron executable @@ -220,7 +226,15 @@ const createSplashWindow = async (): Promise => { pathIndex = '../dist/splash.html'; } - const url = new URL(path.join('file:', dirname, pathIndex)); + if (!fs.existsSync(path.join(dirname, pathIndex))) { + console.error("createSplashScreen(): path doesn't exists: " + path.join(dirname, pathIndex)); + window.close(); + return undefined; + } + + const indexPath = path.join('file:', dirname, pathIndex); + + const url = new URL(indexPath); await window.loadURL(url.href); @@ -297,32 +311,36 @@ async function startMoneroDaemon(commandOptions: string[]): Promise { + monerodProc.onStdOut((data) => { win?.webContents.send('monero-stdout', `${data}`); }); - monerodProcess.onStdErr((data) => { + monerodProc.onStdErr((data) => { win?.webContents.send('monero-stderr', `${data}`); }); - monerodProcess.onError((err: Error) => { + monerodProc.onError((err: Error) => { win?.webContents.send('monero-stderr', `${err.message}`); }); - monerodProcess.onClose((_code: number | null) => { + monerodProc.onClose((_code: number | null) => { const code = _code != null ? _code : -Number.MAX_SAFE_INTEGER; - console.log(`monerod exited with code: ${code}`); - win?.webContents.send('monero-stdout', `monerod exited with code: ${code}`); + const msg = `Process monerod ${monerodProc.pid} exited with code: ${code}`; + console.log(msg); + win?.webContents.send('monero-stdout', msg); win?.webContents.send('monero-close', code); monerodProcess = null; }); + monerodProcess = null; + monerodProcess = monerodProc; + try { await monerodProcess.start(); win?.webContents.send('monerod-started', true); @@ -427,14 +445,14 @@ try { const gotInstanceLock = app.requestSingleInstanceLock(); if (!gotInstanceLock) { - dialog.showErrorBox('', 'Another instance of monerod GUI is running'); + dialog.showErrorBox('', 'Another instance of Monerod GUI is running'); app.quit(); return; } setTimeout(async () => { const splash = await createSplashWindow(); - createWindow(); + await createWindow(); await new Promise((resolve, reject) => { try { @@ -463,11 +481,11 @@ try { } }); - app.on('activate', () => { + app.on('activate', async () => { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (win === null) { - createWindow(); + await createWindow(); } }); diff --git a/app/process/AppChildProcess.ts b/app/process/AppChildProcess.ts index af50026..370a3a4 100644 --- a/app/process/AppChildProcess.ts +++ b/app/process/AppChildProcess.ts @@ -17,6 +17,14 @@ export class AppChildProcess { protected _command: string; protected readonly _args?: string[]; + public get pid(): number { + if (!this._process || this._process.pid == null) { + return -1; + } + + return this._process.pid; + } + protected readonly _handlers: { 'stdout': ((data: string) => void)[], 'stderr': ((err: string) => void)[], diff --git a/app/process/MonerodProcess.ts b/app/process/MonerodProcess.ts index 62a5810..66055a0 100644 --- a/app/process/MonerodProcess.ts +++ b/app/process/MonerodProcess.ts @@ -44,12 +44,12 @@ export class MonerodProcess extends AppChildProcess { let foundUsage: boolean = false; proc.onError((err: Error) => { - console.log(`MonerodProcess.isValidMonerodPath(): '${err.message}'`); + console.log(`MonerodProcess.isValidMonerodPath(): Error: '${err.message}'`); resolve(false); }); proc.onStdErr((err: string) => { - console.log(`MonerodProcess.isValidMonerodPath(): '${err}'`); + console.log(`MonerodProcess.isValidMonerodPath(): Std Error: '${err}'`); resolve(false); }); @@ -58,8 +58,6 @@ export class MonerodProcess extends AppChildProcess { return; } - console.log(`MonerodProcess.isValidMonerodPath(): '${data}'`); - if ( `${data}`.includes('monerod [options|settings] [daemon_command...]') || `${data}`.includes('monerod.exe [options|settings] [daemon_command...]') @@ -70,7 +68,7 @@ export class MonerodProcess extends AppChildProcess { proc.onClose((code: number | null) => { console.log(`MonerodProcess.isValidMonerodPath(): exit code '${code}', found usage: ${foundUsage}`); - resolve(foundUsage); + resolve(foundUsage && code == 0); }); }); @@ -104,6 +102,7 @@ export class MonerodProcess extends AppChildProcess { console.log(message); let firstPatternFound = false; + const waitForPattern = this._args ? !this._args.includes('--version') && !this.args.includes('--help') : true; const patternPromise = new Promise((resolve, reject) => { let firstStdout = true; @@ -112,12 +111,18 @@ export class MonerodProcess extends AppChildProcess { const onStdOut = (out: string) => { if (firstStdout) { firstStdout = false; + + if (!waitForPattern) { + return; + } + timeout = setTimeout(() => { if (this._process && this._process.exitCode == null) { this._process.kill(); } timeout = undefined; - reject(new Error("Timeout out")); + + reject(new Error("MonerodProcess.start(): Timed out")); }, 90*1000); } @@ -128,7 +133,14 @@ export class MonerodProcess extends AppChildProcess { } if (firstPatternFound) { - if(timeout !== undefined) clearTimeout(timeout); + if(timeout !== undefined) { + clearTimeout(timeout); + console.log("MonerodProcess.start(): Cleared timeout"); + } + else { + console.log("MonerodProcess.start(): No timeout found"); + } + resolve(); } else { @@ -144,9 +156,9 @@ export class MonerodProcess extends AppChildProcess { if (!this._process || !this._process.pid) { throw new Error("Monerod process did not start!"); } - try { - const waitForPattern = this._args ? !this._args.includes('--version') && !this.args.includes('--help') : true; - + try { + console.log(`MonerodProcess.start(): wait for pattern: ${waitForPattern}`); + if (waitForPattern) await patternPromise; console.log("Started monerod process pid: " + this._process.pid); @@ -175,27 +187,31 @@ export class MonerodProcess extends AppChildProcess { const promise = new Promise((resolve, reject) => { proc.onError((err: Error) => { - console.log("proc.onError():"); + console.log("MonerodProcess.getVersion(): proc.onError():"); console.error(err); reject(err) }); proc.onStdErr((err: string) => { - console.log("proc.onStdErr()"); + console.log("MonerodProcess.getVersion(): proc.onStdErr()"); console.error(err); reject(new Error(err)); }); proc.onStdOut((version: string) => { - console.log("proc.onStdOut():"); + if (version == '') { + return; + } + + console.log("MonerodProcess.getVersion(): proc.onStdOut():"); console.log(version); resolve(version); }); }); - console.log("Before proc.start()"); + console.log("MonerodProcess.getVersion(): Before proc.start()"); await proc.start(); - console.log("After proc.start()"); + console.log("MonerodProcess.getVersion(): After proc.start()"); return await promise; }