Create a simple Express.js server to shutdown your PC remotely.🤖
Tags: javascript, node, programming, systems
Published: 2021-09-21 17:56:41

## The inspiration

I am a _very_ lazy person. I sometimes go to take a nap & because I'm already in bed, I do not want to stand up & go shutdown my PC myself.

So that's why I thought to myself I might create some small script that listens to a certain port & runs as a _daemon/service_ in the background. That should save me standing up from my bed.

## Choosing how to implement the idea

At first I thought I should make some sockets, given the simplicity of the task, but because this is too low-level for me & as I mentioned before I am too lazy to do everything by hand, I eventually chose Express.JS. Given that it is easy to setup a simple HTTP server very quickly & easily.

## Actual implementation

For the actual implementation.
- I started out by creating a Node.js program with:

```bash
npm init
```
- Then I installed my dependencies:

```bash
npm i express
```

- The programming began with setting up a `GET` method that fires a windows command. To fire command line commands within Node.js use the `child_process` module.

We implement the auxiliary `shutdown` function, that executes the shutdown signal, here I added the time flag `-t` & gave it 30 seconds so the shutdown takes 30 seconds. Feel free to add whatever options you want, maybe even a restart.
> Useful tip use `shutdown -a` to cancel the programmed shutdown or restart.

```javascript
const exec = require('child_process').exec;
// Create shutdown function
function shutdown(callback) {
  exec('shutdown -s -t 0030', 
      function (error, stdout, stderr) { callback(stdout); });
}
```
Here is the first `GET` method:

```javascript
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public/home.html'))
});
```

As you can see I decided to serve an HTML page statically.
This page has a stylized shut-down button. When clicked, the button fires the actual shutdown command and another `GET` request that shows a countdown till shutdown.

```javascript
app.get('/shutdown', (req, res) => {
  res.sendFile(path.join(__dirname, 'public/shutting-down.html'))
  // shutdown computer
  shutdown(function (output) {
    console.log('received shutdown command');
  });
})
```
![server-shutdown1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ysacv1yotalc76va1w1j.gif)

## Serving the static files

Now that the functionality is implemented, you can opt to using a template engine like Pug, but I stuck with simple way of serving static files.
For that you need to use the `static` middleware from Express.js. 
I created a `public` directory where the static files will be & used the middleware to point to it.

```javascript
app.use(express.static("public"));
```
## Styling

I used following snippets for my button styling and the counter. I also used [font-awesome's](https://fontawesome.com/v5.15/icons/power-off) CDN, to get the power-off icon.

[CSS Counter](https://codepen.io/geoffgraham/pen/yLywVbW)
Really well written code you only need to change the duration to your liking and embed it in your served HTML.


[CSS Pulse power-off](https://codepen.io/sashatran/pen/oBVJGP)
You just need to change the color and add the desired icon from font-awesome.

## Creating the service

Under Linux this is no issue using `systemctl`. 
With Windows it is kinda tricky you need to first download and install [nssm](https://nssm.cc/). For brevity I won't explain how to install it. But it should be very simple. And it'll help you a lot.
Now that we have `nssm` installed we now need to convert our `index.js` to an `index.exe`. To do that we need to install the `pkg` dependency globally.

```bash
npm i -g pkg
```
After that we execute following command as an admin:

```bash
pkg index.js -t  node10-win-x64
```
Now we run the following command in `cmd`:
```bash
nssm install
```
Prompting following window, we click on the locate button and choose our `executable`

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2amtafy9mrzc9r4h9zd5.png)

Then we name our service I'll name mine `shutdown-server` and press `Install service`.

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/606yvm30l4gxn72nchc5.png)

Opening the task manager and checking the service tab for our service.
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0swjag5h42kubdc5y3wn.png)

*SUCCESS!* 

## Final project structure
![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2tdbwdv0j7kofk8vgc67.png)