win: Make auto-updater really work

Apparently that PR was never tested.
This commit is contained in:
Cheng Zhao 2015-10-23 19:41:54 +08:00
parent aeafc46ded
commit fae2c7bc7a
2 changed files with 71 additions and 64 deletions

View file

@ -1,57 +1,67 @@
ChildProcess = require 'child_process'
fs = require 'fs'
path = require 'path'
fs = require 'fs'
path = require 'path'
{spawn} = require 'child_process'
appFolder = path.dirname process.execPath # i.e. my-app/app-0.1.13/
rootApplicationFolder = path.resolve appFolder, '..' # i.e. my-app/
updateDotExe = path.join rootApplicationFolder, 'Update.exe'
exeName = path.basename process.execPath
appFolder = path.dirname process.execPath # i.e. my-app/app-0.1.13/
updateExe = path.resolve appFolder, '..', 'Update.exe' # i.e. my-app/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, callback) ->
stdout = ''
spawnUpdate = (args, detached, callback) ->
try
spawnedProcess = ChildProcess.spawn(updateDotExe, args)
spawnedProcess = spawn updateExe, args, {detached}
catch error
# Spawn can throw an error
process.nextTick -> callback?(error, stdout)
# 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
error = null
spawnedProcess.on 'error', (processError) -> error ?= processError
spawnedProcess.on 'close', (code, signal) ->
error ?= new Error("Command failed: #{signal ? code}") if code isnt 0
error?.code ?= code
error?.stdout ?= stdout
callback?(error, stdout)
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
processStart = (callback) ->
spawnUpdate(['--processStart', exeName], callback)
# Process terminated with error.
if code isnt 0
return callback "Command failed: #{signal ? code}\n#{stderr}"
download = (callback) ->
spawnUpdate ['--download', @updateUrl], (error, stdout) ->
# 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()
json = stdout.trim().split('\n').pop()
update = JSON.parse(json)?.releasesToApply?.pop?()
catch error
error.stdout = stdout
return callback(error)
catch
return callback "Invalid result:\n#{stdout}"
callback(null, update)
callback null, update
update = (updateUrl, callback) ->
spawnUpdate ['--update', updateUrl], callback
# 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 = ->
fs.accessSync(updateDotExe, fs.R_OK)
exports.processStart = processStart
exports.download = download
exports.update = update
try
fs.accessSync updateExe, fs.R_OK
return true
catch
return false