'Exec, ExecSync, Spawn, SpawnSync fails in production on multiple MAC machines

Solved -- Official Electron bug solved in 17.0.2

I'm trying to write a cross-platform app that utilizes child processes to execute commands. I ran into a problem where the script wouldn't work on some Mac computers except the one mac. I wrote a simple electron app to just call execSync and echo "hello". This app works in dev mode and works on 1 of the 2 macs I have. I've tested it on a friend's third Mac and failed as well. Here are the only differences on the macs from a simple overhead.

  • The Successful mac - 10.11.6 (has vscode, nodeJS, electron installed etc)
  • Failed Mac - 10.13.6 (has vscode, nodeJS, electron installed etc)
  • Friends Failed mac - 10.14.6 (clean, no coding stuff installed)

I'm not sure what else to try or figure out. The code should simply open the electron app window and console log "hello" on the two failure macs I get this response.

renderer.js:11 (which is my reason => console.log(reason) line)

Error: Error invoking remote method 'testExecSync': Error: Command failed: echo hello

If it helps, this simple app works on windows as well. I just do not understand what is missing from the two macs that failed. Am I not packaging something when the electron is being built?

I have tried other electron builder versions and nodeJS but with no surprise didn't make any effect when packaging the app.

This happens with any of the child processes I've tested, same result/success rates.

Appreciate any suggestions or thoughts to try!

Cheers!

UPDATE! - Edit

I've tested further with a simple node.JS and that runs fine. My conclusion has to be from the electron packaging and permissions/privledges. I've managed to get the app working only if the app is running by the root. I tested by going into the contents of the package and using the following

sudo /Applications/simpleMacOSTest.app/Contents/MacOS/SimpleMacOSTest

I confirmed the app was running as root using activity monitor. Works as root, doesn't work when user runs even though user is acting as adminstarator.

The question is then, how do I get around this to package my electron app? I could simply write a bash terminal script to run said app using the sudo command above.Is there a way to fix this in node/electron?

index.js

const { app, BrowserWindow, ipcMain } = require("electron")
const process = require("child_process")
const path = require("path")

let mainWindow

app.whenReady().then(() => {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 800,
    show: true,
    autoHideMenuBar: true,
    webPreferences: {
      //   devTools: false,
      nodeIntegration: false, // is default value after Electron v5
      contextIsolation: true, // protect against prototype pollution
      enableRemoteModule: false, // turn off remote
      preload: path.join(__dirname, "preload.js"), // use a preload script
    },
  })
  mainWindow.webContents.openDevTools()
  mainWindow.loadFile(path.join(__dirname + "/index.html"))
})

ipcMain.handle("testExecSync", async (_, args) => {
  const result = process.execSync(args[0], args[1]).toString()
  return result
})

preload.js

const { ipcRenderer, contextBridge } = require("electron")

const api = {
  testExecSync: (args) => ipcRenderer.invoke("testExecSync", args),
}

contextBridge.exposeInMainWorld("api", api)

renderer.js

async function testCMD() {
  return api.testExecSync(["echo hello", { encoding: "UTF-8" }])
}

testCMD().then(
  (value) => {
    console.log(value)
    return value
  },
  (reason) => {
    console.log(reason)
  }
)

package.json

{
  "name": "simplemacostest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "electron .",
    "build": "electron-builder"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^17.0.0",
    "electron-builder": "^22.14.13"
  }
}


Solution 1:[1]

After grueling hours of debugging. It's either a bug or some strange fix/patch in electron 17+. I've reverted to electron 16.0.9 and that allows child_processes to work when the app is packaged.

As well, paths must be absolute using child_processes when packaged. Not sure if that's a result of electron 17+ but thought I just add in case someone else was running into more errors.

Cheers!

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 DMDComposer