| const homedir = require('os').homedir(); | const homedir = require('os').homedir(); | ||||
| var ENV = Object.assign({}, process.env); // Shallow clone it. | |||||
| function sysAddPathVar(path){ | function sysAddPathVar(path){ | ||||
| // Object.assign({ | // Object.assign({ | ||||
| // inherit: true, shell: true, env: ENV, title: `${command} ${args}` | // inherit: true, shell: true, env: ENV, title: `${command} ${args}` | ||||
| const fs = require('fs') | const fs = require('fs') | ||||
| const cliargs = utils.cliargs; | const cliargs = utils.cliargs; | ||||
| const processedArgs = cliargs(process.argv.slice(2)); | |||||
| const processedArgs = cliargs(process.argv); | |||||
| if(!processedArgs.wd){ | |||||
| if(process.env.wd){ | |||||
| } | |||||
| else { | |||||
| process.env.wd = process.cwd(); | |||||
| if(process.cwd() === __dirname) { | |||||
| // This script was launched in the same dir. | |||||
| } | |||||
| } | |||||
| } | |||||
| else process.env.wd = processedArgs.wd | |||||
| var ENV = Object.assign({}, process.env); // Shallow clone it. | |||||
| console.dir(processedArgs) | console.dir(processedArgs) | ||||
| // PB : TODO -- defaults for valuless arguments if passed. | // PB : TODO -- defaults for valuless arguments if passed. | ||||
| // Object.keys(processedArgs).forEach(a=>{ | // Object.keys(processedArgs).forEach(a=>{ | ||||
| if (__isElevated) { | if (__isElevated) { | ||||
| try { | try { | ||||
| op[processedArgs.label || processedArgs._[0] || 'undefined']() | |||||
| op[processedArgs.label || processedArgs._[0] || 'undefined'](processedArgs) | |||||
| } | } | ||||
| catch (e) { | catch (e) { | ||||
| console.error('Error Invalid command : ' + e) | console.error('Error Invalid command : ' + e) | ||||
| console.log('result : ' + JSON.stringify(r)) | console.log('result : ' + JSON.stringify(r)) | ||||
| Object.keys(processedArgs).forEach((v) => { v != '_' ? namedArgs.push('--' + v + '=' + processedArgs[v]) : null; }) | Object.keys(processedArgs).forEach((v) => { v != '_' ? namedArgs.push('--' + v + '=' + processedArgs[v]) : null; }) | ||||
| // PB : TODO -- Convert all the cli args back to string. | // PB : TODO -- Convert all the cli args back to string. | ||||
| var args = [`${selectedinstance.root}/.elxr/run-${runtimestamp}/windowselevate.hta`].concat(processedArgs._).concat(namedArgs.join(' ')); args.push('--runas=self'); | |||||
| var args = [`${selectedinstance.root}/.elxr/run-${runtimestamp}/windowselevate.hta`].concat(processedArgs._) | |||||
| namedArgs.length > 0 ? args = args.concat(namedArgs.join(' ')) : null; | |||||
| args.push('--runas=self'); | |||||
| // 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.. | ||||
| console.dir(processedArgs) | |||||
| // console.dir(processedArgs._) | |||||
| // console.dir(namedArgs.join(' ')) | |||||
| console.dir(args) | |||||
| // throw 'test' | |||||
| return nodeShellExec('MSHTA', [`"${args.join('" "')}"`] | return nodeShellExec('MSHTA', [`"${args.join('" "')}"`] | ||||
| , { | , { | ||||
| // sourecpathandfile should include name of file name | // sourecpathandfile should include name of file name | ||||
| targetfilename = cmdopts.targetfilename || processedArgs._[1] | targetfilename = cmdopts.targetfilename || processedArgs._[1] | ||||
| // console.log(processedArgs) | // console.log(processedArgs) | ||||
| if(!targetfilename) Promise.reject('error no file provided for linking') | |||||
| if(!targetfilename) return Promise.reject('error no file provided for linking') | |||||
| targetdir = cmdopts.targetdir || process.env.wd | targetdir = cmdopts.targetdir || process.env.wd | ||||
| sourecpathandfile = cmdopts.sourecpathandfile || path.normalize(`../../node_modules/chess-server-lib/common/models/${targetfilename}`) | sourecpathandfile = cmdopts.sourecpathandfile || path.normalize(`../../node_modules/chess-server-lib/common/models/${targetfilename}`) | ||||
| }) | }) | ||||
| } | } | ||||
| var launchpath = path.normalize(process.cwd()) | |||||
| var launchpath = path.resolve(path.normalize(process.env.wd)) | |||||
| var thisscriptdir = path.normalize(__dirname); // PB : TODO -- Thisscriptdir could be dislocated when run as a standalone file... We need to detect this where and how we were run. | var thisscriptdir = path.normalize(__dirname); // PB : TODO -- Thisscriptdir could be dislocated when run as a standalone file... We need to detect this where and how we were run. | ||||
| // The easisest would be to ask for a target directory and default to current dir.... | // The easisest would be to ask for a target directory and default to current dir.... | ||||
| var instanceroot = path.normalize(thisscriptdir) === path.normalize(launchpath) ? path.normalize(thisscriptdir + '/..') : launchpath ; | |||||
| // path.dirname(launchpath).split(path.sep).pop() | |||||
| var parent = path.dirname(launchpath); | |||||
| var pp = launchpath; | |||||
| var instancediscoverytasks = []; | |||||
| while(parent !== pp){ | |||||
| instancediscoverytasks.push( | |||||
| ((pa)=>{ | |||||
| var p = pa; | |||||
| return function(){ | |||||
| return hasElxr(p).then((value)=>{ | |||||
| if(value) return p | |||||
| throw { value : false }; | |||||
| }) | |||||
| } | |||||
| })(pp) | |||||
| ) | |||||
| pp = parent; | |||||
| parent = path.dirname(parent); | |||||
| } | |||||
| var instanceroot = null | |||||
| var detectInstanceRoot = any(instancediscoverytasks, true, true).then( ir => instanceroot = ir.pVal ).catch(()=>{ | |||||
| instanceroot = path.normalize(thisscriptdir) === path.normalize(launchpath) ? path.normalize(thisscriptdir + '/..') : launchpath ; | |||||
| }) | |||||
| // PB : TODO -- Embed this in the build instead of inlining it. | // PB : TODO -- Embed this in the build instead of inlining it. | ||||
| // Also attepmt to load from ../chess-config/... | // Also attepmt to load from ../chess-config/... | ||||
| var mainTasks = []; | var mainTasks = []; | ||||
| function verifyAndInstallPrerequisites() { | function verifyAndInstallPrerequisites() { | ||||
| fs.writeFileSync(ensureDirectoryExistence(path.normalize(`${selectedinstance.root}/${downloadsdir}/readme.txt`)), `${getVersion()} Your local downloads for this instance`) | |||||
| // PB : TODO include and build from files... using rollup.. | |||||
| var downloadbatch = | |||||
| `::************************************************************************** | |||||
| :Download_ <url> <File> | |||||
| Powershell.exe ^ | |||||
| $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'; ^ | |||||
| [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols; ^ | |||||
| (New-Object System.Net.WebClient).DownloadFile('%1','%2') | |||||
| exit /b | |||||
| ::**************************************************************************` | |||||
| fs.writeFileSync(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`, downloadbatch) | |||||
| var windowselevate = | |||||
| ` | |||||
| <html><HTA:APPLICATION ID="windowselevate" icon="#"/> | |||||
| <script language="vbscript"> | |||||
| document.title = "elxr control panel" | |||||
| self.ResizeTo 200,600 | |||||
| Sub Window_Onload | |||||
| self.MoveTo (screen.availWidth - (document.body.clientWidth + 40)),10 | |||||
| End Sub | |||||
| Set objShell = CreateObject("WScript.Shell") | |||||
| Set objENV = objShell.Environment("Process") | |||||
| dim NODE_ENV | |||||
| NODE_ENV = objENV("NODE_ENV") | |||||
| </script> | |||||
| <script language="javascript"> | |||||
| //WINDOWSTATE="minimize" SHOWINTASKBAR="no" SYSMENU="no" CAPTION="no" | |||||
| // https://devblogs.microsoft.com/scripting/how-can-i-pass-command-line-variables-to-an-hta-when-it-starts/ | |||||
| // alert(windowselevate.commandLine) | |||||
| var args = windowselevate.commandLine.split('"').slice(3); | |||||
| // alert(args) | |||||
| var processedArgs = { _ : [] } | |||||
| var namedArgs = []; | |||||
| for(var item in args){ | |||||
| if(args[item].charAt(0) === '-'){ | |||||
| namedArgs.push(args[item]) | |||||
| var split = args[item].split('='); | |||||
| processedArgs[split[0].slice(2)] = split[1] || true; | |||||
| } | |||||
| else processedArgs._.push(args[item]); | |||||
| } | |||||
| // args = args.forEach(function(item){ }) | |||||
| // alert('processedArgs._ : ' + processedArgs._); | |||||
| // alert(processedArgs.runas); | |||||
| // PB : TODO -- Convert all the cli args back to string. | |||||
| var cargs = (processedArgs.debug ? '--inspect-brk=9228' : '') + ' elxr ' + processedArgs._.join(' ') + ' ' + namedArgs.join(' '); | |||||
| // alert(cargs) | |||||
| var shell = new ActiveXObject('shell.application'); | |||||
| // alert('launching node privilged. ' + processedArgs['nodepath']) | |||||
| // shell.ShellExecute('where', 'node', '', '', 10); | |||||
| // shell.ShellExecute('cmd.exe', '/k notepad.exe', '', 'runas', 1); | |||||
| // shell.ShellExecute('cmd.exe ', '/k node "' + cargs + '"', '', 'runas', 1); | |||||
| shell.ShellExecute('node', cargs, '', 'runas', 1); | |||||
| // shell.ShellExecute(processedArgs['nodepath'], cargs, '', 'runas', 1); | |||||
| var fso = new ActiveXObject('Scripting.FileSystemObject'); | |||||
| window.onload = function() { | |||||
| document.body.style.backgroundColor = 'black'; | |||||
| document.body.style.fontFamily = 'arial'; | |||||
| var log = document.createElement('div'); | |||||
| log.innerHTML='Please Wait'; | |||||
| function l(msg){ log.innerHTML+= msg; }; | |||||
| log.style.color = 'blue'; | |||||
| log.style.width = '95%'; | |||||
| log.id = 'log'; | |||||
| document.body.appendChild(log); | |||||
| l('<Br/>Current config : ') | |||||
| l('<Br/>NODE_ENV = ' + NODE_ENV) | |||||
| l('<Br/>cmd = ' + processedArgs._[0]) | |||||
| processedArgs._[1] === 'use' ? l('<Br/>using = ' + processedArgs._[2]) : null; | |||||
| l('<Br/><Br/>') | |||||
| var timer = function(){ | |||||
| l('.'); | |||||
| if(fso.FileExists("run.done")) close(); | |||||
| else window.setTimeout(timer, 1000); | |||||
| }; | |||||
| window.setTimeout(timer, 3000); | |||||
| }; | |||||
| </script> | |||||
| </html> | |||||
| ` | |||||
| fs.writeFileSync(`${selectedinstance.root}/.elxr/run-${runtimestamp}/windowselevate.hta`, windowselevate) | |||||
| var downloadtasks = []; | var downloadtasks = []; | ||||
| var installtasks = []; | var installtasks = []; | ||||
| prerequisites.forEach(preq => { | prerequisites.forEach(preq => { | ||||
| } | } | ||||
| var generateDependencies = function(){ | |||||
| // PB : TODO -- Keep only the last n runs... | |||||
| // Currently it retains 2*n when proc needs to be relaunched in elevated mode !!! | |||||
| ensureDirectoryExistence(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`) | |||||
| fs.writeFileSync(ensureDirectoryExistence(path.normalize(`${selectedinstance.root}/${downloadsdir}/readme.txt`)), `${getVersion()} Your local downloads for this instance`) | |||||
| // PB : TODO include and build from files... using rollup.. | |||||
| var downloadbatch = | |||||
| `::************************************************************************** | |||||
| :Download_ <url> <File> | |||||
| Powershell.exe ^ | |||||
| $AllProtocols = [System.Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'; ^ | |||||
| [System.Net.ServicePointManager]::SecurityProtocol = $AllProtocols; ^ | |||||
| (New-Object System.Net.WebClient).DownloadFile('%1','%2') | |||||
| exit /b | |||||
| ::**************************************************************************` | |||||
| fs.writeFileSync(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`, downloadbatch) | |||||
| var windowselevate = | |||||
| ` | |||||
| <html><HTA:APPLICATION ID="windowselevate" icon="#"/> | |||||
| <script language="vbscript"> | |||||
| document.title = "elxr control panel" | |||||
| self.ResizeTo 200,600 | |||||
| Sub Window_Onload | |||||
| self.MoveTo (screen.availWidth - (document.body.clientWidth + 40)),10 | |||||
| End Sub | |||||
| Set objShell = CreateObject("WScript.Shell") | |||||
| Set objENV = objShell.Environment("Process") | |||||
| dim NODE_ENV | |||||
| NODE_ENV = objENV("NODE_ENV") | |||||
| </script> | |||||
| <script language="javascript"> | |||||
| //WINDOWSTATE="minimize" SHOWINTASKBAR="no" SYSMENU="no" CAPTION="no" | |||||
| // https://devblogs.microsoft.com/scripting/how-can-i-pass-command-line-variables-to-an-hta-when-it-starts/ | |||||
| // alert(windowselevate.commandLine) | |||||
| var args = windowselevate.commandLine.split('"').slice(3); | |||||
| // alert(args) | |||||
| var processedArgs = { _ : [] } | |||||
| var namedArgs = []; | |||||
| namedArgs.push('--wd=' + objENV('wd')) | |||||
| // alert(namedArgs) | |||||
| for(var item in args){ | |||||
| if(args[item].charAt(0) === '-'){ | |||||
| namedArgs.push(args[item]) | |||||
| var split = args[item].split('='); | |||||
| processedArgs[split[0].slice(2)] = split[1] || true; | |||||
| } | |||||
| else processedArgs._.push(args[item]); | |||||
| } | |||||
| // args = args.forEach(function(item){ }) | |||||
| // alert('processedArgs._ : ' + processedArgs._); | |||||
| // alert(processedArgs.runas); | |||||
| // alert(objENV('wd')) | |||||
| // PB : TODO -- Convert all the cli args back to string. | |||||
| // __filename will sure we are launhed using the same entry point. | |||||
| var cargs = (processedArgs.debug ? '--inspect-brk=9228' : '') + ' ${path.basename(__filename)} ' + processedArgs._.join(' ') + ' ' + namedArgs.join(' '); | |||||
| // alert(cargs) | |||||
| var shell = new ActiveXObject('shell.application'); | |||||
| // alert('launching node privilged. ' + processedArgs['nodepath']) | |||||
| // shell.ShellExecute('where', 'node', '', '', 10); | |||||
| // shell.ShellExecute('cmd.exe', '/k notepad.exe', '', 'runas', 1); | |||||
| // shell.ShellExecute('cmd.exe ', '/k node "' + cargs + '"', '', 'runas', 1); | |||||
| shell.ShellExecute('node', cargs, '', 'runas', 1); | |||||
| // shell.ShellExecute(processedArgs['nodepath'], cargs, '', 'runas', 1); | |||||
| var fso = new ActiveXObject('Scripting.FileSystemObject'); | |||||
| window.onload = function() { | |||||
| document.body.style.backgroundColor = 'black'; | |||||
| document.body.style.fontFamily = 'arial'; | |||||
| var log = document.createElement('div'); | |||||
| log.innerHTML='Please Wait'; | |||||
| function l(msg){ log.innerHTML+= msg; }; | |||||
| log.style.color = 'blue'; | |||||
| log.style.width = '95%'; | |||||
| log.id = 'log'; | |||||
| document.body.appendChild(log); | |||||
| l('<Br/>Current config : ') | |||||
| l('<Br/>NODE_ENV = ' + NODE_ENV) | |||||
| l('<Br/>cmd = ' + processedArgs._[0]) | |||||
| processedArgs._[1] === 'use' ? l('<Br/>using = ' + processedArgs._[2]) : null; | |||||
| l('<Br/><Br/>') | |||||
| var timer = function(){ | |||||
| l('.'); | |||||
| if(fso.FileExists("run.done")) close(); | |||||
| else window.setTimeout(timer, 1000); | |||||
| }; | |||||
| window.setTimeout(timer, 3000); | |||||
| }; | |||||
| </script> | |||||
| </html> | |||||
| ` | |||||
| fs.writeFileSync(`${selectedinstance.root}/.elxr/run-${runtimestamp}/windowselevate.hta`, windowselevate) | |||||
| } | |||||
| var startElxr = function() { | var startElxr = function() { | ||||
| const retaincount = 2 | const retaincount = 2 | ||||
| var min = runtimestamp; | var min = runtimestamp; | ||||
| }) | }) | ||||
| .then(()=>{ | .then(()=>{ | ||||
| generateDependencies(); | |||||
| if(noprerequisites[processedArgs._[0]] | if(noprerequisites[processedArgs._[0]] | ||||
| || skipprereqs[processedArgs._[0]] | || skipprereqs[processedArgs._[0]] | ||||
| ) { | ) { | ||||
| } | } | ||||
| else return true | else return true | ||||
| }) | }) | ||||
| if (!skipprerequisites && !__isElevated || processedArgs.forceprereqs && !__isElevated ) mainTasks.push(verifyAndInstallPrerequisites); | |||||
| mainTasks.push(maintask) | |||||
| return any(mainTasks); | |||||
| } | } | ||||
| else return true; | else return true; | ||||
| }) | }) | ||||
| .then(()=>{ | .then(()=>{ | ||||
| // PB : TODO -- Keep only the last n runs... | |||||
| // Currently it retains 2*n when proc needs to be relaunched in elevated mode !!! | |||||
| ensureDirectoryExistence(`${selectedinstance.root}/.elxr/run-${runtimestamp}/download.bat`) | |||||
| if (!skipprerequisites && !__isElevated || processedArgs.forceprereqs && !__isElevated ) mainTasks.push(verifyAndInstallPrerequisites); | |||||
| mainTasks.push(maintask) | |||||
| return any(mainTasks); | |||||
| }) | }) | ||||
| } | } | ||||
| acquireElevationState().then(() => { | |||||
| return startElxr() | |||||
| detectInstanceRoot.then(()=>{ | |||||
| return acquireElevationState().then(() => { | |||||
| return startElxr() | |||||
| }) | |||||
| }) | }) | ||||
| // detect if alread installed -> Take no action. | // detect if alread installed -> Take no action. |