Added code to support self-updating windows service

Ylian Saint-Hilaire committed Aug 8, 2019 at 12:43 UTC b1779a7ef4094b12626832e850c06375fd0473fc
2 files changed +63 -5
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.3.9-l",
3 + "version": "0.3.9-m",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
winservice.js
+62 -4
@@ -1,5 +1,5 @@
1 /**
2 -* @description MeshCentral main module
2 +* @description Windows Service Launcher
3 * @author Ylian Saint-Hilaire
4 * @copyright Intel Corporation 2018-2019
5 * @license Apache-2.0
@@ -13,6 +13,64 @@
13 /*jshint esversion: 6 */
14 "use strict";
15
16 -// This module is only called when MeshCentral is running as a Windows service.
17 -// In this case, we don't want to start a child process, so we launch directly without arguments.
18 -require('./meshcentral.js').mainStart({ "launch": true });
16 +function start() {
17 + if (require('os').platform() != 'win32') { console.log('ERROR: Win32 only'); process.exit(255); return; }
18 +
19 + try {
20 + const fs = require('fs');
21 + const path = require('path');
22 +
23 + // Search for meshcentral.js
24 + var cwd = null;
25 + var runarg = null;
26 + if (fs.existsSync(path.join(__dirname, 'meshcentral.js'))) {
27 + runarg = path.join(__dirname, 'meshcentral.js');
28 + cwd = __dirname;
29 + } else if (fs.existsSync(path.join(__dirname, '../node_modules/meshcentral/meshcentral.js'))) {
30 + runarg = path.join(__dirname, '../node_modules/meshcentral/meshcentral.js');
31 + cwd = path.join(__dirname, '..');
32 + } else if (fs.existsSync(path.join(__dirname, '../meshcentral/meshcentral.js'))) {
33 + runarg = path.join(__dirname, '../meshcentral/meshcentral.js');
34 + cwd = path.join(__dirname, '../meshcentral');
35 + }
36 + if (runarg == null) { console.log('ERROR: Unable to find MeshCentral.js'); process.exit(255); return; }
37 +
38 + // Setup libraries
39 + const args = require(path.join(cwd, 'node_modules/minimist'))(process.argv.slice(2));
40 + const nodewindows = require(path.join(cwd, 'node_modules/node-windows'));
41 + const service = nodewindows.Service;
42 + const eventlogger = nodewindows.EventLogger;
43 + const servicelog = new eventlogger('MeshCentral');
44 +
45 + // Check if we need to install, start, stop, remove ourself as a background service
46 + if (((args.install == true) || (args.uninstall == true) || (args.start == true) || (args.stop == true) || (args.restart == true))) {
47 + var env = [], xenv = ['user', 'port', 'aliasport', 'mpsport', 'mpsaliasport', 'redirport', 'exactport', 'debug'];
48 + for (var i in xenv) { if (args[xenv[i]] != null) { env.push({ name: 'mesh' + xenv[i], value: args[xenv[i]] }); } } // Set some args as service environement variables.
49 + var svc = new service({ name: 'MeshCentral', description: 'MeshCentral Remote Management Server', script: path.join(__dirname, 'winservice.js'), env: env, wait: 2, grow: 0.5 });
50 + svc.on('install', function () { console.log('MeshCentral service installed.'); svc.start(); });
51 + svc.on('uninstall', function () { console.log('MeshCentral service uninstalled.'); process.exit(); });
52 + svc.on('start', function () { console.log('MeshCentral service started.'); process.exit(); });
53 + svc.on('stop', function () { console.log('MeshCentral service stopped.'); if (args.stop) { process.exit(); } if (args.restart) { console.log('Holding 5 seconds...'); setTimeout(function () { svc.start(); }, 5000); } });
54 + svc.on('alreadyinstalled', function () { console.log('MeshCentral service already installed.'); process.exit(); });
55 + svc.on('invalidinstallation', function () { console.log('Invalid MeshCentral service installation.'); process.exit(); });
56 +
57 + if (args.install == true) { try { svc.install(); } catch (e) { logException(e); } }
58 + if (args.stop == true || args.restart == true) { try { svc.stop(); } catch (e) { logException(e); } }
59 + if (args.start == true || args.restart == true) { try { svc.start(); } catch (e) { logException(e); } }
60 + if (args.uninstall == true) { try { svc.uninstall(); } catch (e) { logException(e); } }
61 + return;
62 + }
63 +
64 + // This module is only called when MeshCentral is running as a Windows service.
65 + // In this case, we don't want to start a child process, so we launch directly without arguments.
66 + require(cwd).mainStart({ "launch": true });
67 + } catch (ex) { console.log(ex); }
68 +
69 + // Logging funtions
70 + function logException(e) { e += ''; logErrorEvent(e); }
71 + function logInfoEvent(msg) { if (servicelog != null) { servicelog.info(msg); } console.log(msg); }
72 + function logWarnEvent(msg) { if (servicelog != null) { servicelog.warn(msg); } console.log(msg); }
73 + function logErrorEvent(msg) { if (servicelog != null) { servicelog.error(msg); } console.error(msg); }
74 +}
75 +
76 +start();
\ No newline at end of file