Search code examples
javascriptnode.jswindows-servicesdaemonnode-windows

Restarting a service in node-windows


Using the node-windows package, I am installing a node server locally as a service. Having then an interface to modify the .env file, when I actually modify the configurations of the .env and save the changes, the issue is that the service does not restart as it is supposed to, in order to acknowledge these changes. Can anyone guide me if there any other way to handle service restarts from this package, or any other workarounds similiar? I actually am trying to handle the restart like this:

const path = require("path");
let Service = require("node-windows").Service;
let EventLogger = require("node-windows").EventLogger;
const Messages= require("./models/messagesModel").getInstance();    
let filePathServer = path.resolve(__dirname, "app.backend.js");

class ServiceInstall {

    constructor(envConfig) {

    this.log = new EventLogger(envConfig.SERVICE_NAME);
    this.svc = new Service({
        name: envConfig.SERVICE_NAME,
        description: envConfig.SERVICE_DESCRIPTION,
        script: filePathServer,
        wait: envConfig.SERVICE_WAIT,
        grow: envConfig.SERVICE_GROW
    });
    }

    installWindowsService() {
        // event handlers to install the service
    }

    restartWindowsService(){
            this.svc.on("stop", () => {
                this.log.info("Service " + this.svc.name + " stopped!");
                Messages.info("Service " + this.svc.name + " stopped!");
            });
            this.svc.on("start", () => {
                this.log.info("Service " + this.svc.name + " started!");
                Messages.info("Service " + this.svc.name + " started!");
            });
            this.svc.restart();
        }

    }

module.exports = ServiceInstall;

Solution

  • During the install process, node-windows essentially performs two steps:

    1. Creates a .exe file by making a copy from winsw.exe and make corresponding entry in Windows Registry, so Windows can recognize this .exe as a Windows Service.

    2. Use values passed into the Service constructor to generate a .xml file of the same name.

    What this means is that once the .xml has been created, any changes that apply to inputs to the constructor function would not be carried into the .xml file, unless you do a complete re-install of the service [using svc.uninstall() followed by svc.install()]

    If you want dynamically changing inputs, but without requiring a re-install, you should put those values in a config.json and then simply require that config.json from within the script you are trying to host as a Windows Service.

    Now, if you make a change to config.json you just need to restart the service to reflect the change.

    Also, if you don't want to manually do the restart everytime config.json changes, use nodemon in execPath instead of node in the config object passed to the Service constructor.