| var cli = require('./cliverse') | var cli = require('./cliverse') | ||||
| var nodeShellExec = cli.nodeShellExec; | var nodeShellExec = cli.nodeShellExec; | ||||
| function elevatedRunIPCWriteMessage( target, m ) { | |||||
| fs.writeFileSync(target, ', ' + JSON.stringify( m ), { 'flag': 'a+' }) | |||||
| } | |||||
| var __isElevated = null; | var __isElevated = null; | ||||
| var shell_verse = { | var shell_verse = { | ||||
| // getCommonTask is agnostic of whether we are running in an elevated shell or not. It runs in either case. | // getCommonTask is agnostic of whether we are running in an elevated shell or not. It runs in either case. | ||||
| , elevatedRunner( taskToRun, inBatch ){ | , elevatedRunner( taskToRun, inBatch ){ | ||||
| // PB : TODO -- Should be called only when we are in an elevated shell that was already requested from an unelevated shell with a batch of tasks. | // PB : TODO -- Should be called only when we are in an elevated shell that was already requested from an unelevated shell with a batch of tasks. | ||||
| try { | try { | ||||
| var runlogjson = `${selectedinstance.root}/.elxr/run-${runtimestamp}/run.log` | |||||
| var __runasresult = null; | var __runasresult = null; | ||||
| return taskToRun().then((r)=>{ | return taskToRun().then((r)=>{ | ||||
| // PB : TODO -- Every elevation should have its own messaging file. Async writes from multiple processes are a problem here... | // PB : TODO -- Every elevation should have its own messaging file. Async writes from multiple processes are a problem here... | ||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify( { info : taskToRun.info, success: true }), { 'flag': 'a+' }) | |||||
| elevatedRunIPCWriteMessage( runlogjson, ', ' + JSON.stringify( { info : taskToRun.info, success: true }) ) | |||||
| if(!inBatch) fs.writeFileSync('run.done', 'success') // PB : TODO -- This should be done conditionally if we are running inproc. | if(!inBatch) fs.writeFileSync('run.done', 'success') // PB : TODO -- This should be done conditionally if we are running inproc. | ||||
| return __runasresult = r; | return __runasresult = r; | ||||
| }) | }) | ||||
| .catch((e) => { | .catch((e) => { | ||||
| fs.writeFileSync('run.log', ', ' + JSON.stringify(e), { 'flag': 'a+' }) | |||||
| elevatedRunIPCWriteMessage( runlogjson, ', ' + JSON.stringify(e ) ) | |||||
| if(!inBatch)fs.writeFileSync('run.done', 'failure') | if(!inBatch)fs.writeFileSync('run.done', 'failure') | ||||
| console.error(e) | console.error(e) | ||||
| }) | }) | ||||
| } | } | ||||
| , requestElevation(elevatedRunner, taskToRun) { | , requestElevation(elevatedRunner, taskToRun) { | ||||
| // PB : TODO -- Multiple parallel request elevations should be queued into a promise. | |||||
| // PB : TODO -- Multiple parallel request elevations should be queued into a batch and serialized as a single promise. | |||||
| var processedArgs = taskToRun.processedArgs, selectedinstance = taskToRun.selectedinstance , statuslog = taskToRun.statuslog | var processedArgs = taskToRun.processedArgs, selectedinstance = taskToRun.selectedinstance , statuslog = taskToRun.statuslog | ||||
| // Wait for the runas to complete before we read it. | // Wait for the runas to complete before we read it. | ||||
| try { | try { | ||||
| fs.unlinkSync('run.done') | |||||
| fs.unlinkSync('run.log') | |||||
| fs.unlinkSync('run.done') // Need a unique file for aech elevated run. | |||||
| } | } | ||||
| catch (e) { } //Ignore | catch (e) { } //Ignore | ||||
| var args = [`${selectedinstance.root}/.elxr/run-${taskToRun.runtimestamp}/windowselevate.hta`].concat(processedArgs._) | var args = [`${selectedinstance.root}/.elxr/run-${taskToRun.runtimestamp}/windowselevate.hta`].concat(processedArgs._) | ||||
| namedArgs.length > 0 ? args = args.concat(namedArgs.join(' ')) : null; | namedArgs.length > 0 ? args = args.concat(namedArgs.join(' ')) : null; | ||||
| args.push('--runas=self'); | args.push('--runas=self'); | ||||
| var elevatedruntimestamp = (new Date()).getTime() | |||||
| args.push(`--runtimestamp=${elevatedruntimestamp}`); | |||||
| // args.push('--nodepath=' + r.messages[r.messages.length - 1]) | // args.push('--nodepath=' + r.messages[r.messages.length - 1]) | ||||
| // if (!processedArgs.node_env) args.push('--node_env=' + ENV.NODE_ENV) | // if (!processedArgs.node_env) args.push('--node_env=' + ENV.NODE_ENV) | ||||
| // if (processedArgs.debug) args.push('--debug=true') // Enable to debug elevated.. | // if (processedArgs.debug) args.push('--debug=true') // Enable to debug elevated.. | ||||
| // runas returned. | // runas returned. | ||||
| try { | try { | ||||
| // PB : TODO -- Log is comma prefixed. Needs to be proper JSON. | // PB : TODO -- Log is comma prefixed. Needs to be proper JSON. | ||||
| var runaslog = JSON.parse('[ { "success" : true, "result" : "started"}' + fs.readFileSync('run.log', { flags: 'a+' }) + ']'); | |||||
| var runlogjson = `${selectedinstance.root}/.elxr/run-${elevatedruntimestamp}/run.log` | |||||
| var runaslog = JSON.parse('[' + fs.readFileSync(runlogjson, { flags: 'a+' }) + ']'); | |||||
| try { fs.unlinkSync(runlogjson) } catch(e){ } // PB : TODO -- Have a unique file for each elevated run. | |||||
| // console.log( "runaslog : " + runaslog.length ) | |||||
| // Assemble elevated run results into the main run log | |||||
| runaslog.forEach((logEntry) => { | runaslog.forEach((logEntry) => { | ||||
| statuslog.statuslog(logEntry.success ? null : logEntry, logEntry) | statuslog.statuslog(logEntry.success ? null : logEntry, logEntry) | ||||
| logEntry.success ? (console.log(['success :' + logEntry.result]), console.log((logEntry.messages || []).join(' '))) : (console.error(['error :' + logEntry.result]), console.error((logEntry.messages || []).join(' '))) | logEntry.success ? (console.log(['success :' + logEntry.result]), console.log((logEntry.messages || []).join(' '))) : (console.error(['error :' + logEntry.result]), console.error((logEntry.messages || []).join(' '))) | ||||
| }) | }) | ||||
| .catch(err => console.error('Elevation failed : ' + err)); | .catch(err => console.error('Elevation failed : ' + err)); | ||||
| }) | }) | ||||
| } | |||||
| } | |||||
| , iswin(){ return true} | , iswin(){ return true} | ||||
| , islin(){ return false} | , islin(){ return false} | ||||
| } | } |