diff --git a/lib/gui/app/modules/image-writer.ts b/lib/gui/app/modules/image-writer.ts index 650a698a..c4ab0ab7 100644 --- a/lib/gui/app/modules/image-writer.ts +++ b/lib/gui/app/modules/image-writer.ts @@ -15,7 +15,6 @@ */ import { Drive as DrivelistDrive } from 'drivelist'; -import * as electron from 'electron'; import * as sdk from 'etcher-sdk'; import { Dictionary } from 'lodash'; import * as ipc from 'node-ipc'; @@ -25,6 +24,7 @@ import * as path from 'path'; import * as packageJSON from '../../../../package.json'; import * as errors from '../../../shared/errors'; import * as permissions from '../../../shared/permissions'; +import { getAppPath } from '../../../shared/utils'; import { SourceMetadata } from '../components/source-selector/source-selector'; import * as flashState from '../models/flash-state'; import * as selectionState from '../models/selection-state'; @@ -93,11 +93,7 @@ function terminateServer() { } function writerArgv(): string[] { - let entryPoint = path.join( - electron.remote.app.getAppPath(), - 'generated', - 'child-writer.js', - ); + let entryPoint = path.join(getAppPath(), 'generated', 'child-writer.js'); // AppImages run over FUSE, so the files inside the mount point // can only be accessed by the user that mounted the AppImage. // This means we can't re-spawn Etcher as root from the same diff --git a/lib/shared/catalina-sudo/sudo.ts b/lib/shared/catalina-sudo/sudo.ts index 5422cbcd..b6c39f0c 100644 --- a/lib/shared/catalina-sudo/sudo.ts +++ b/lib/shared/catalina-sudo/sudo.ts @@ -15,11 +15,12 @@ */ import { execFile } from 'child_process'; -import { app, remote } from 'electron'; import { join } from 'path'; import { env } from 'process'; import { promisify } from 'util'; +import { getAppPath } from '../utils'; + const execFileAsync = promisify(execFile); const SUCCESSFUL_AUTH_MARKER = 'AUTHENTICATION SUCCEEDED'; @@ -37,7 +38,7 @@ export async function sudo( env: { PATH: env.PATH, SUDO_ASKPASS: join( - (app || remote.app).getAppPath(), + getAppPath(), __dirname, 'sudo-askpass.osascript.js', ), diff --git a/lib/shared/utils.ts b/lib/shared/utils.ts index 36c4c021..f312dee5 100755 --- a/lib/shared/utils.ts +++ b/lib/shared/utils.ts @@ -15,6 +15,7 @@ */ import axios from 'axios'; +import { app, remote } from 'electron'; import { Dictionary } from 'lodash'; import * as errors from './errors'; @@ -47,3 +48,16 @@ export async function delay(duration: number): Promise { setTimeout(resolve, duration); }); } + +export function getAppPath(): string { + return ( + (app || remote.app) + .getAppPath() + // With macOS universal builds, getAppPath() returns the path to an app.asar file containing an index.js file which will + // include the app-x64 or app-arm64 folder depending on the arch. + // We don't care about the app.asar file, we want the actual folder. + .replace(/\.asar$/, () => + process.platform === 'darwin' ? '-' + process.arch : '', + ) + ); +} diff --git a/webpack.config.ts b/webpack.config.ts index 48d25f6e..fc195838 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -120,7 +120,15 @@ function fetchWasm(...where: string[]) { } catch { } function appPath() { - return Path.isAbsolute(__dirname) ? __dirname : Path.join(electron.remote.app.getAppPath(), 'generated'); + return Path.isAbsolute(__dirname) ? + __dirname : + Path.join( + // With macOS universal builds, getAppPath() returns the path to an app.asar file containing an index.js file which will + // include the app-x64 or app-arm64 folder depending on the arch. + // We don't care about the app.asar file, we want the actual folder. + electron.remote.app.getAppPath().replace(/\\.asar$/, () => process.platform === 'darwin' ? '-' + process.arch : ''), + 'generated' + ); } scriptDirectory = Path.join(appPath(), 'modules', ${whereStr}, '/'); `; @@ -238,7 +246,19 @@ const commonConfig = { "return await readFile(Path.join(__dirname, '..', 'blobs', filename));", replace: outdent` const { app, remote } = require('electron'); - return await readFile(Path.join((app || remote.app).getAppPath(), 'generated', __dirname.replace('node_modules', 'modules'), '..', 'blobs', filename)); + return await readFile( + Path.join( + // With macOS universal builds, getAppPath() returns the path to an app.asar file containing an index.js file which will + // include the app-x64 or app-arm64 folder depending on the arch. + // We don't care about the app.asar file, we want the actual folder. + (app || remote.app).getAppPath().replace(/\\.asar$/, () => process.platform === 'darwin' ? '-' + process.arch : ''), + 'generated', + __dirname.replace('node_modules', 'modules'), + '..', + 'blobs', + filename + ) + ); `, }), // Use the libext2fs.wasm file in the generated folder