import { spawn } from 'child_process' import process from 'process' const buildWindowsInstallCommand = (installerPath) => ({ command: 'cmd.exe', args: [ '/d', '/s', '/c', `timeout /t 2 /nobreak >NUL && msiexec.exe /i "${installerPath}" /qn /norestart` ] }) export const launchWindowsInstaller = ( app, installerPath, webContents, { sendProgress, getInstallErrorMessage } ) => { const { command, args } = buildWindowsInstallCommand(installerPath) console.log('[app-update] launching installer:', { installerPath, command, args, shellCommand: args.join(' '), platform: process.platform }) sendProgress(webContents, { phase: 'installing', percent: 100, message: 'Installing update. Farm Control will restart automatically.' }) return new Promise((resolve, reject) => { let installerOutput = '' const installerProcess = spawn(command, args, { detached: true, stdio: ['ignore', 'pipe', 'pipe'], windowsHide: true }) installerProcess.stdout?.on('data', (data) => { const text = data.toString() installerOutput += text console.log('[app-update] installer stdout:', text) }) installerProcess.stderr?.on('data', (data) => { const text = data.toString() installerOutput += text console.error('[app-update] installer stderr:', text) }) installerProcess.on('spawn', () => { console.log('[app-update] installer spawned, pid:', installerProcess.pid) }) installerProcess.on('error', (error) => { console.error('[app-update] installer spawn error:', error) sendProgress(webContents, { phase: 'error', percent: null, message: error?.message || 'Failed to start update installer.' }) reject(error) }) installerProcess.on('exit', (code, signal) => { console.log('[app-update] installer exited:', { code, signal, output: installerOutput }) if (code !== 0) { const message = getInstallErrorMessage(null, installerOutput) sendProgress(webContents, { phase: 'error', percent: null, message }) reject(new Error(message)) return } sendProgress(webContents, { phase: 'installing', percent: 100, message: 'Installation complete. Restarting Farm Control...' }) resolve() }) installerProcess.unref() }) }