fs = require 'fs' path = require 'path' {spawn} = require 'child_process' ### i.e. my-app/app-0.1.13/ ### appFolder = path.dirname process.execPath ### i.e. my-app/Update.exe ### updateExe = path.resolve appFolder, '..', 'Update.exe' exeName = path.basename process.execPath ### Spawn a command and invoke the callback when it completes with an error and the output from standard out. ### spawnUpdate = (args, detached, callback) -> try spawnedProcess = spawn updateExe, args, {detached} catch error ### Shouldn't happen, but still guard it. ### process.nextTick -> callback error return stdout = '' stderr = '' spawnedProcess.stdout.on 'data', (data) -> stdout += data spawnedProcess.stderr.on 'data', (data) -> stderr += data errorEmitted = false spawnedProcess.on 'error', (error) -> errorEmitted = true callback error spawnedProcess.on 'exit', (code, signal) -> ### We may have already emitted an error. ### return if errorEmitted ### Process terminated with error. ### if code isnt 0 return callback "Command failed: #{signal ? code}\n#{stderr}" ### Success. ### callback null, stdout ### Start an instance of the installed app. ### exports.processStart = (callback) -> spawnUpdate ['--processStart', exeName], true, -> ### Download the releases specified by the URL and write new results to stdout. ### exports.download = (updateURL, callback) -> spawnUpdate ['--download', updateURL], false, (error, stdout) -> return callback(error) if error? try ### Last line of output is the JSON details about the releases ### json = stdout.trim().split('\n').pop() update = JSON.parse(json)?.releasesToApply?.pop?() catch return callback "Invalid result:\n#{stdout}" callback null, update ### Update the application to the latest remote version specified by URL. ### exports.update = (updateURL, callback) -> spawnUpdate ['--update', updateURL], false, callback ### Is the Update.exe installed with the current application? ### exports.supported = -> try fs.accessSync updateExe, fs.R_OK return true catch return false