Service installer and "manager"


#1

Hi!

Hi have to make a cross-platform application. This application have to be a setup that install a service (for the moment on windows, linux later). She must have a tray menu or a window to manage it.

I tried to do it with electron + electron-builder and node-windows. For now my service juste run an Express server which listen on 8080.
When I launch my app with electron in dev all works great. My window allow me to install/uninstall the service, when started express works on localhost:8080, I can open/close the electron app without breaking the service.

My problem is after electron-builder make the unpacked and the setup. These exe files install the service and it is display with the ‘running’ status. But locahost:8080 don’t works.

Can anyone help me to solve it or say how can I done it without electron ?

package.json :

Summary
{
  // omitted
  "scripts": {
    "start": "electron ./src/electron.js", // start for dev testing
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "build --win" // build unpacked and setup in /dist
  },
  "build": {
    "asar": false,
    "files": [
      "!logs/"
    ],
    "win": {
      "target": [
        "nsis"
      ],
      "requestedExecutionLevel": "requireAdministrator"
    },
    "mac": {
      "target": [
        "dmg"
      ]
    },
    "linux": {
      "target": [
        "AppImage"
      ]
    },
    "nsis": {
      "oneClick": false,
      "perMachine": true,
      "allowElevation": true
    }
  },
  "dependencies": {
    "node-windows": "^0.1.14"
  },
  "devDependencies": {
    "electron": "^4.0.8",
    "electron-builder": "^20.38.5",
    "express": "^4.16.4"
  }
}

src/electron.js

Summary
'use strict';
const { app, BrowserWindow, Tray, Menu } = require('electron');
const { Service } = require('node-windows');
const path = require('path');

let appShell;
let appUrl = 'file://' + __dirname + '/index.html';
let service;

function createElectronShell() {
 appShell = new BrowserWindow({ width: 800, height: 600 });
 appShell.loadURL(appUrl);
 appShell.on('closed', () => { appShell = null; });

 const template = [
   {
      label: 'Service',
      submenu: [
      {
        label: 'Start service',
        click() {
          createService();
        }
      },
      {
        label: 'Stop service',
        click() {
          stopService();
        }
      },
      {
        label: 'Uninstall service',
        click() {
          uninstallService();
        }
      }
    ]
   }
 ];
 const menu = Menu.buildFromTemplate(template)
 Menu.setApplicationMenu(menu);
}

app.on('ready', createElectronShell);
app.on('window-all-closed', () => {
   if (process.platform !== 'darwin')
      app.quit();
   stopService();
});

app.on('activate', () => {
   if (appShell == null)
      createElectronShell();
});

function createService() {
 if (!service) {
   service = new Service({
      name: 'electron-POC',
      description: 'A simple node js listener',
      script: path.join(__dirname, 'listener.js')
   });
    service.on('install', () => {
      service.start();
    });
    service.install();
  }
  else {
    service.start();
  }
}

function stopService() {
  if (service) {
    service.stop();
  }
}

function uninstallService() {
  if (service) {
    service.uninstall();
  }
}

src/listener.js

Summary
const express = require('express');
const app = express();

app.get('/', (req, res) => {
   res.send('<h1>Server is up and running on port 8080</h1>');
});

app.get('*', (req, res) => {
   res.send('<p>Server is running on port 8080</p>');
});

app.listen(8080, () => {
   console.log('The server is running in port 8080');
});