mirror of
https://github.com/Ylianst/MeshAgent
synced 2026-02-07 04:03:17 +00:00
Updated console mode self-updater
This commit is contained in:
@@ -234,7 +234,19 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (argc > 1 && strcasecmp(argv[1], "-updaterversion") == 0)
|
||||
{
|
||||
#ifdef WIN32
|
||||
DWORD dummy;
|
||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "1\n", 2, &dummy, NULL);
|
||||
#else
|
||||
ignore_result(write(STDOUT_FILENO, "1\n", 2));
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
wmain_free(argv);
|
||||
#endif
|
||||
return(0);
|
||||
}
|
||||
#if defined(_LINKVM) && defined(__APPLE__)
|
||||
if (argc > 1 && strcasecmp(argv[1], "-kvm0") == 0)
|
||||
{
|
||||
@@ -291,12 +303,17 @@ char* crashMemory = ILib_POSIX_InstallCrashHandler(argv[0]);
|
||||
{
|
||||
if (argc >= 2 && strnlen_s(argv[1], 9) >= 8 && strncmp(argv[1], "-update:", 8) == 0)
|
||||
{
|
||||
// -update:"C:\Users\Public\Downloads\MeshManageability\Debug\MeshConsol2.exe"
|
||||
MeshAgent_PerformSelfUpdate(argv[0], argv[1] + 8, argc, argv);
|
||||
#ifdef WIN32
|
||||
wmain_free(argv);
|
||||
#endif
|
||||
return 0;
|
||||
ILibMemory_AllocateRaw(integratedJavaScript, 1024);
|
||||
if (argv[1][8] == '*')
|
||||
{
|
||||
// New Style
|
||||
integratedJavaScriptLen = sprintf_s(integratedJavaScript, 1024, "require('agent-installer').update(false, '%s');", argc > 1 ? argv[2] : "null");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Legacy
|
||||
integratedJavaScriptLen = sprintf_s(integratedJavaScript, 1024, "require('agent-installer').update(false, ['%s']);", argv[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef WIN32
|
||||
|
||||
@@ -21,6 +21,7 @@ limitations under the License.
|
||||
#include <WinBase.h>
|
||||
#include "wincrypto.h"
|
||||
#include <shellscalingapi.h>
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#include "agentcore.h"
|
||||
@@ -2468,6 +2469,71 @@ void MeshServer_selfupdate_continue(MeshAgentHostContainer *agent)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
if (agent->JSRunningAsService == 0)
|
||||
{
|
||||
// Windows Console Mode updater
|
||||
if (duk_peval_string(agent->meshCoreCtx, "require('agent-installer').consoleUpdate();") != 0)
|
||||
{
|
||||
printf("%s", duk_safe_to_string(agent->meshCoreCtx, -1));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//// Check updater version
|
||||
//if (agent->JSRunningAsService == 0)
|
||||
//{
|
||||
// char* updateFilePath = MeshAgent_MakeAbsolutePath(agent->exePath, ".update.exe"); // uses ILibScratchPad2
|
||||
// duk_push_sprintf(agent->meshCoreCtx, "require('agent-installer').updaterVersion('%s');", updateFilePath); // [code]
|
||||
// if (duk_peval(agent->meshCoreCtx) == 0) { agent->updaterVersion = duk_get_int(agent->meshCoreCtx, -1); } // [version]
|
||||
// duk_pop(agent->meshCoreCtx); // ...
|
||||
//}
|
||||
|
||||
#ifndef WIN32
|
||||
if (duk_peval_string(agent->meshCoreCtx, "require('MeshAgent').getStartupOptions();") == 0) // [obj]
|
||||
{
|
||||
char *pth = "";
|
||||
size_t i = 0;
|
||||
size_t lines = 2;
|
||||
size_t len = 0;
|
||||
duk_del_prop_string(agent->meshCoreCtx, -1, "fakeUpdate");
|
||||
|
||||
if (duk_peval_string(agent->meshCoreCtx, "process.execPath.split('/').pop();") == 0)
|
||||
{
|
||||
pth = (char*)duk_get_lstring(agent->meshCoreCtx, -1, &len);
|
||||
len += 1;
|
||||
}
|
||||
duk_swap_top(agent->meshCoreCtx, -2); // [path][obj]
|
||||
duk_enum(agent->meshCoreCtx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [path][obj][enum]
|
||||
while (duk_next(agent->meshCoreCtx, -1, 1)) // [path][obj][enum][key][value]
|
||||
{
|
||||
++lines;
|
||||
len += snprintf(NULL, 0, "--%s=\"%s\" ", duk_get_string(agent->meshCoreCtx, -2), duk_get_string(agent->meshCoreCtx, -1));
|
||||
duk_pop_2(agent->meshCoreCtx); // [path][obj][enum]
|
||||
}
|
||||
duk_pop(agent->meshCoreCtx); // [path][obj]
|
||||
agent->execparams = (char**)ILibMemory_SmartAllocateEx(lines * sizeof(char*), len);
|
||||
|
||||
i += (1 + sprintf_s(ILibMemory_Extra(agent->execparams), ILibMemory_ExtraSize(agent->execparams), "%s", pth));
|
||||
lines = 1;
|
||||
agent->execparams[0] = ILibMemory_Extra(agent->execparams);
|
||||
|
||||
duk_enum(agent->meshCoreCtx, -1, DUK_ENUM_OWN_PROPERTIES_ONLY); // [path][obj][enum]
|
||||
while (duk_next(agent->meshCoreCtx, -1, 1)) // [path][obj][enum][key][value]
|
||||
{
|
||||
len = sprintf_s(ILibMemory_Extra(agent->execparams) + i, ILibMemory_ExtraSize(agent->execparams) - i, "--%s=\"%s\"", duk_get_string(agent->meshCoreCtx, -2), duk_get_string(agent->meshCoreCtx, -1));
|
||||
agent->execparams[lines] = ILibMemory_Extra(agent->execparams) + i;
|
||||
i += (len + 1);
|
||||
duk_pop_2(agent->meshCoreCtx); // [path][obj][enum]
|
||||
++lines;
|
||||
}
|
||||
agent->execparams[lines] = NULL;
|
||||
duk_pop(agent->meshCoreCtx); // [path][obj]
|
||||
}
|
||||
duk_pop_2(agent->meshCoreCtx); // ...
|
||||
#endif
|
||||
|
||||
// Everything looks good, lets perform the update
|
||||
if (agent->logUpdate != 0)
|
||||
{
|
||||
@@ -5476,7 +5542,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
#ifdef WIN32
|
||||
if(strcmp(agentHost->meshServiceName, "Mesh Agent") !=0)
|
||||
#else
|
||||
if (strcmp(agentHost->meshServiceName, "Mesh Agent") != 0)
|
||||
if (strcmp(agentHost->meshServiceName, "meshagent") != 0)
|
||||
#endif
|
||||
{
|
||||
startParms = ILibMemory_SmartAllocateEx(ILibMemory_Size(agentHost->meshServiceName) + 30, ILibBase64EncodeLength(ILibMemory_Size(agentHost->meshServiceName) + 30));
|
||||
@@ -5504,8 +5570,8 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
#endif
|
||||
if (agentHost->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Updating..."); }
|
||||
#ifdef WIN32
|
||||
// Windows version
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s -update:*%s %s", updateFilePath, agentHost->JSRunningAsService!=0?"S":"C", startParms==NULL?"":(char*)ILibMemory_Extra(startParms));
|
||||
// Windows Service Updater
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s -update:*%s %s", updateFilePath, agentHost->JSRunningAsService != 0 ? "S" : "C", startParms == NULL ? "" : (char*)ILibMemory_Extra(startParms));
|
||||
if (!CreateProcessW(NULL, ILibUTF8ToWide(ILibScratchPad, -1), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &info, &processInfo))
|
||||
{
|
||||
// We triedI to execute a bad executable... not good. Lets try to recover.
|
||||
@@ -5524,7 +5590,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
{
|
||||
CloseHandle(processInfo.hProcess);
|
||||
CloseHandle(processInfo.hThread);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (agentHost->JSRunningAsService != 0)
|
||||
{
|
||||
@@ -5541,7 +5607,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
{
|
||||
// FreeBSD doesn't support hot-swapping the binary
|
||||
if (agentHost->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Handing off to child to complete"); }
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s -exec \"var s=require('service-manager').manager.getService('meshagent');s.stop();require('fs').copyFileSync('%s', '%s');s.start();process.exit();\"", updateFilePath, updateFilePath, agentHost->exePath);
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "%s -exec \"var s=require('service-manager').manager.getService('%s');s.stop();require('fs').copyFileSync('%s', '%s');s.start();process.exit();\"", updateFilePath, agentHost->meshServiceName, updateFilePath, agentHost->exePath);
|
||||
ignore_result(MeshAgent_System(ILibScratchPad));
|
||||
}
|
||||
else
|
||||
@@ -5552,7 +5618,7 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
{
|
||||
case MeshAgent_Posix_PlatformTypes_LAUNCHD:
|
||||
if (agentHost->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Complete... [kickstarting service]"); }
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "launchctl kickstart -k system/meshagent"); // Restart the service
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "launchctl kickstart -k system/%s", agentHost->meshServiceName); // Restart the service
|
||||
ignore_result(system(ILibScratchPad));
|
||||
break;
|
||||
case MeshAgent_Posix_PlatformTypes_SYSTEMD:
|
||||
@@ -5565,12 +5631,12 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
break;
|
||||
case MeshAgent_Posix_PlatformTypes_INITD:
|
||||
if (agentHost->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Complete... Calling Service restart (INITD)"); }
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "service meshagent restart"); // Restart the service
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "service %s restart", agentHost->meshServiceName); // Restart the service
|
||||
ignore_result(MeshAgent_System(ILibScratchPad));
|
||||
break;
|
||||
case MeshAgent_Posix_PlatformTypes_INIT_UPSTART:
|
||||
if (agentHost->logUpdate != 0) { ILIBLOGMESSSAGE("SelfUpdate -> Complete... Calling initctl restart (UPSTART)"); }
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "initctl restart meshagent"); // Restart the service
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "initctl restart %s", agentHost->meshServiceName); // Restart the service
|
||||
ignore_result(MeshAgent_System(ILibScratchPad));
|
||||
break;
|
||||
default:
|
||||
@@ -5590,8 +5656,13 @@ int MeshAgent_Start(MeshAgentHostContainer *agentHost, int paramLen, char **para
|
||||
struct stat results;
|
||||
stat(agentHost->exePath, &results); // This the mode of the current executable
|
||||
chmod(updateFilePath, results.st_mode); // Set the new executable to the same mode as the current one.
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "\"%s\" -update:* %s &", updateFilePath, startParms == NULL ? "" : (char*)ILibMemory_Extra(startParms));
|
||||
|
||||
remove(agentHost->exePath);
|
||||
sprintf_s(ILibScratchPad, sizeof(ILibScratchPad), "cp %s %s", updateFilePath, agentHost->exePath);
|
||||
if (system(ILibScratchPad)) {}
|
||||
|
||||
execv(agentHost->exePath, agentHost->execparams);
|
||||
_exit(1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -5619,6 +5690,7 @@ void MeshAgent_Destroy(MeshAgentHostContainer* agent)
|
||||
if (agent->multicastDiscoveryKey != NULL) { free(agent->multicastDiscoveryKey); agent->multicastDiscoveryKey = NULL; }
|
||||
if (agent->multicastServerUrl != NULL) { free(agent->multicastServerUrl); agent->multicastServerUrl = NULL; }
|
||||
if (agent->meshServiceName != NULL) { ILibMemory_Free(agent->meshServiceName); agent->meshServiceName = NULL; }
|
||||
if (agent->execparams != NULL) { ILibMemory_Free(agent->execparams); agent->execparams = NULL; }
|
||||
#ifdef WIN32
|
||||
if (agent->shCore != NULL)
|
||||
{
|
||||
|
||||
@@ -237,6 +237,8 @@ typedef struct MeshAgentHostContainer
|
||||
MeshAgent_Posix_PlatformTypes platformType;
|
||||
int JSRunningAsService;
|
||||
int JSRunningWithAdmin;
|
||||
int updaterVersion;
|
||||
char **execparams;
|
||||
char *meshServiceName;
|
||||
#if defined(_WINSERVICE)
|
||||
int runningAsConsole;
|
||||
|
||||
@@ -26,6 +26,10 @@ limitations under the License.
|
||||
#include "ILibDuktape_EventEmitter.h"
|
||||
#include "ILibDuktape_ScriptContainer.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#define ILibDuktape_ChildProcess_Process "\xFF_ChildProcess_Process"
|
||||
#define ILibDuktape_ChildProcess_MemBuf "\xFF_ChildProcess_MemBuf"
|
||||
|
||||
@@ -502,6 +506,62 @@ duk_ret_t ILibDuktape_ChildProcess_execFile(duk_context *ctx)
|
||||
duk_push_pointer(ctx, manager); duk_put_prop_string(ctx, -2, ILibDuktape_ChildProcess_Manager);
|
||||
return(1);
|
||||
}
|
||||
|
||||
duk_ret_t ILibDuktape_ChildProcess_execve(duk_context *ctx)
|
||||
{
|
||||
int nargs = duk_get_top(ctx);
|
||||
char **args;
|
||||
char **env;
|
||||
int i;
|
||||
char *path = (char*)duk_require_string(ctx, 0);
|
||||
|
||||
args = (char**)ILibMemory_SmartAllocate(sizeof(char*) * (1 + duk_get_length(ctx, -1)));
|
||||
for (i = 0; i < (int)duk_get_length(ctx, -1); ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, (duk_uarridx_t)i); // [array][arg]
|
||||
args[i] = duk_get_string(ctx, -1);
|
||||
duk_pop(ctx); // [array]
|
||||
}
|
||||
|
||||
if (nargs > 2 && duk_is_object(ctx, 2) && duk_has_prop_string(ctx, 2, "env"))
|
||||
{
|
||||
duk_get_prop_string(ctx, 2, "env"); // [obj]
|
||||
}
|
||||
else
|
||||
{
|
||||
duk_eval_string(ctx, "process.env"); // [obj]
|
||||
}
|
||||
duk_push_array(ctx); // [obj][array]
|
||||
duk_enum(ctx, -2, DUK_ENUM_OWN_PROPERTIES_ONLY); // [obj][array][enum]
|
||||
while (duk_next(ctx, -1, 1)) // [obj][array][enum][key][value]
|
||||
{
|
||||
duk_push_sprintf(ctx, "%s=%s", duk_get_string(ctx, -2), duk_get_string(ctx, -1)); //[value][string]
|
||||
duk_array_push(ctx, -5); // [obj][array][enum][key][value]
|
||||
duk_pop_2(ctx); // [obj][array][enum]
|
||||
}
|
||||
duk_pop(ctx); // [obj][array]
|
||||
|
||||
env = (char**)ILibMemory_SmartAllocate(sizeof(char*) * (1 + duk_get_length(ctx, -1)));
|
||||
for (i = 0; i < (int)duk_get_length(ctx, -1); ++i)
|
||||
{
|
||||
duk_get_prop_index(ctx, -1, (duk_uarridx_t)i); // [array][arg]
|
||||
env[i] = duk_get_string(ctx, -1);
|
||||
duk_pop(ctx); // [array]
|
||||
}
|
||||
#ifndef WIN32
|
||||
execve(path, args, env);
|
||||
return(ILibDuktape_Error(ctx, "_execve() returned error: %d ", errno));
|
||||
#else
|
||||
if (_execve(path, args, env) < 0)
|
||||
{
|
||||
return(ILibDuktape_Error(ctx, "_execve() failed"));
|
||||
}
|
||||
else
|
||||
{
|
||||
_exit(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
|
||||
{
|
||||
duk_push_object(ctx);
|
||||
@@ -511,6 +571,8 @@ void ILibDuktape_ChildProcess_PUSH(duk_context *ctx, void *chain)
|
||||
ILibDuktape_CreateFinalizer(ctx, ILibDuktape_ChildProcess_Manager_Finalizer);
|
||||
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "execFile", ILibDuktape_ChildProcess_execFile, DUK_VARARGS);
|
||||
ILibDuktape_CreateInstanceMethod(ctx, "_execve", ILibDuktape_ChildProcess_execve, DUK_VARARGS);
|
||||
|
||||
duk_push_object(ctx);
|
||||
duk_push_int(ctx, 0);
|
||||
duk_put_prop_string(ctx, -2, "DEFAULT");
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,6 +31,21 @@ Object.defineProperty(Array.prototype, 'getParameter',
|
||||
return (defaultValue);
|
||||
}
|
||||
});
|
||||
Object.defineProperty(Array.prototype, 'getParameterIndex',
|
||||
{
|
||||
value: function (name)
|
||||
{
|
||||
var i;
|
||||
for (i = 0; i < this.length; ++i)
|
||||
{
|
||||
if (this[i].startsWith('--' + name + '='))
|
||||
{
|
||||
return (i);
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
});
|
||||
|
||||
function checkParameters(parms)
|
||||
{
|
||||
@@ -568,13 +583,20 @@ module.exports =
|
||||
|
||||
function sys_update(isservice, b64)
|
||||
{
|
||||
console.setDestination(console.Destinations.LOGFILE);
|
||||
|
||||
// This is run on the 'updated' agent.
|
||||
|
||||
var parm = b64 != null ? JSON.parse(Buffer.from(b64, 'base64').toString()) : null;
|
||||
var service = null;
|
||||
var serviceLocation = "";
|
||||
var px;
|
||||
|
||||
console.log(isservice, parm);
|
||||
console.setInfoLevel(1);
|
||||
console.info1('sys_update(' + isservice + ', ' + JSON.stringify(parm) + ')');
|
||||
if ((px = parm.getParameterIndex('fakeUpdate')) >= 0)
|
||||
{
|
||||
console.info1('Removing "fakeUpdate" parameter');
|
||||
parm.splice(px, 1);
|
||||
}
|
||||
|
||||
if (isservice)
|
||||
{
|
||||
@@ -605,9 +627,6 @@ function sys_update(isservice, b64)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if (!global._interval)
|
||||
{
|
||||
global._interval = setInterval(sys_update, 60000, isservice, b64);
|
||||
@@ -615,8 +634,18 @@ function sys_update(isservice, b64)
|
||||
|
||||
if (isservice === false)
|
||||
{
|
||||
// Console Mode
|
||||
serviceLocation = process.execPath.split('.update.exe').join('.exe');
|
||||
//
|
||||
// Console Mode (LEGACY)
|
||||
//
|
||||
if (process.platform == 'win32')
|
||||
{
|
||||
serviceLocation = process.execPath.split('.update.exe').join('.exe');
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceLocation = process.execPath.substring(0, process.execPath.length - 7);
|
||||
}
|
||||
|
||||
if (serviceLocation != process.execPath)
|
||||
{
|
||||
try
|
||||
@@ -625,15 +654,14 @@ function sys_update(isservice, b64)
|
||||
}
|
||||
catch (ce)
|
||||
{
|
||||
console.log('Could not copy file.. Trying again in 60 seconds');
|
||||
return;
|
||||
console.log('\nAn error occured while updating agent.');
|
||||
process.exit();
|
||||
}
|
||||
}
|
||||
|
||||
// Copied agent binary... Need to start agent in console mode
|
||||
console.log('Agent update complete. Starting in console mode...');
|
||||
process._exit();
|
||||
return;
|
||||
console.log('\nAgent update complete... Please re-start agent.');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
|
||||
@@ -667,5 +695,41 @@ function sys_update(isservice, b64)
|
||||
});
|
||||
}
|
||||
|
||||
function agent_updaterVersion(updatePath)
|
||||
{
|
||||
if (updatePath == null) { updatePath = process.execPath; }
|
||||
var child = require('child_process').execFile(updatePath, [updatePath.split(process.platform == 'win32' ? '\\' : '/').pop(), '-updaterversion']);
|
||||
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
|
||||
child.waitExit();
|
||||
if(child.stdout.str.trim() == '')
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (parseInt(child.stdout.str));
|
||||
}
|
||||
}
|
||||
|
||||
function win_consoleUpdate()
|
||||
{
|
||||
// This is run from the 'old' agent, to copy the 'updated' agent.
|
||||
var copy = [];
|
||||
copy.push("try { require('fs').copyFileSync(process.execPath, process.execPath.split('.update.exe').join('.exe')); }");
|
||||
copy.push("catch (x) { console.log('\\nError updating Mesh Agent.'); process.exit(); }");
|
||||
copy.push("if(require('child_process')._execve==null) { console.log('\\nMesh Agent was updated... Please re-run from the command line.'); process.exit(); }");
|
||||
copy.push("require('child_process')._execve(process.execPath.split('.update.exe').join('.exe'), [process.execPath.split('.update.exe').join('.exe'), 'run']);");
|
||||
var args = [];
|
||||
args.push(process.execPath.split('.exe').join('.update.exe'));
|
||||
args.push('-b64exec');
|
||||
args.push(Buffer.from(copy.join('\r\n')).toString('base64'));
|
||||
console.info1('_execve("' + process.execPath.split('.exe').join('.update.exe') + '", ' + JSON.stringify(args) + ');');
|
||||
require('child_process')._execve(process.execPath.split('.exe').join('.update.exe'), args);
|
||||
}
|
||||
|
||||
module.exports.update = sys_update;
|
||||
module.exports.updaterVersion = agent_updaterVersion;
|
||||
if (process.platform == 'win32')
|
||||
{
|
||||
module.exports.consoleUpdate = win_consoleUpdate;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user