[Electron] Créer une application CPU Monitor

Créer une application simple avec Electron : CPU Monitor + Installer

Dans cet article, nous écrirons une application simple pour surveiller l'utilisation du processeur à l'aide de HTML/CSS et JavaScript avec le framework Electron et apprendrons également comment empaqueter l'application et créer un programme d'installation pour la distribution avec squirrel & electron-builder.

 

Prérequis et configuration du projet

Avant de pouvoir commencer, vous devez d'abord installer Node.js et Git . Il suffit de télécharger le programme d'installation à partir de leurs sites Web et de suivre les instructions.

Une fois à la racine de votre projet, nous allons d'abord ouvrir un git bash et installer l'électron avec la commande npm install.

npm install electron -g

 

 

Pour créer un nouveau projet, vous pouvez le créer from-scratch si vous le souhaitez, mais il existe un outil appelé Electron Forge qui vous aidera à configurer un projet très rapidement avec du code squelette pour commencer.

Donc une fois l'électron installé. Nous allons installer Electron Forge en utilisant npm

npm install create-electron-app -g

 

Une fois l'installation terminée, vous pouvez créer un nouveau projet en tapant "create-electron-app" suivi d'un nom de projet.

Electron Forge créera l'arborescence de votre projet pour vous

create-electron-app my-cpu-app

 

 

Logique applicative

Le projet est livré avec le code squelette et le script nécessaire et prêt à être exécuté. Alors depuis ce nouveau dossier, exécutons-le !

npm run start

 

 

Vous devriez voir l'application Hello world comme celle-ci.

Un texte simple avec la console développeur ouverte. l'app ressemble à google chrome puisque Electron est basé sur Chromium . Cela signifie que vous pouvez utiliser HTML, CSS et JavaScript pour coder cette application comme vous le faites sur un site Web.

electron-cpu-app-helloworld

Le code de cette web-application se trouve dans le dossier "src". Cette Architecture est généré par Electron Forge.

Depuis VSCode vous pouvez ouvrir le dossier.

Le fichier JavaScript "index.js" comprends la logique principale de l'application. Il existe une fonction pour créer une nouvelle fenêtre pour l'application. Ensuite, chargez le fichier html dans cette fenêtre, etc.

C'est pourquoi j'ai utilisé Electron Forge pour créer un nouveau projet au lieu d'en créer un nouveau à partir de zéro. Je ne veux tout simplement pas réécrire ce code à chaque fois lors du démarrage d'un nouveau projet.

 

 

Maintenant notre workspace est prêt, il est temps de commencer à coder votre web-app.

Puisque nous allons créer une application pour surveiller l'utilisation du processeur, nous devrons utiliser l'appel le module de Node.js os-utils.

npm install os-utils

 

 

Il faut ensuite déclarer le module dans le fichier "index.js".

 

const os = require('os-utils');

 

 

 Parce que le fichier JavaScript principal et le fichier HTML s'exécutent sur un processus séparé.

Le fichier "index.js" est sur un processus principal et le HTML dans la fenêtre du navigateur est sur le processus de rendu. Si nous voulons mettre les données du processus principal dans le processus de rendu. Nous aurons besoin d'utiliser une communication inter-processus (IPC)

Ainsi, dans le processus principal, nous enverrons les données à l'aide de mainWindow.webContents.send.
Ensuite, vous pouvez nommer le message afin de pouvoir le recevoir correctement dans le processus de rendu. Nous appellerons la méthode cpuUsage qui renverra la valeur avec la fonction de rappel. Je vais également tirer l'utilisation de la mémoire et la mémoire totale du système à titre d'exemple.

  

Index.js

Utilisez également setInterval pour récupérer les données toutes les secondes depuis la création de fenêtre createWindow.

setInterval(() => {
  os.cpuUsage(function(v){
    mainWindow.webContents.send('cpu',v*100);
    mainWindow.webContents.send('mem',os.freememPercentage()*100);
    mainWindow.webContents.send('total-mem',os.totalmem()/1024);
  });
},1000);

 

 

Le nodeIntegration & contextIsolation doivent être activés dans la directive mainWindow (les préférences web de la fenêtre du navigateur) afin que nous puissions utiliser le module node.js dans le fichier HTML pour recevoir le message.

const mainWindow = new BrowserWindow({
  width: 1024,
  height: 768,
  webPreferences: {
    nodeIntegration: true, contextIsolation: false
  }
});

 

 

Pour désactiver la l'ouverture automatique de la console, commenter la fonction

mainWindow.webContents.openDevTools();

 

 

Vous devriez avoir quelque chose comme ceci

index.js

const { app, BrowserWindow } = require('electron');
const path = require('path');
const os = require('os-utils');
 
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
if (require('electron-squirrel-startup')) { // eslint-disable-line global-require
  app.quit();
}
 
const createWindow = () => {
  // Create the browser window.
  const mainWindow = new BrowserWindow({
    width: 1024,
    height: 768,
    icon: __dirname + '/favicon.ico',
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false
    }
  });
   
  // and load the index.html of the app.
  mainWindow.loadFile(path.join(__dirname, 'index.html'));
 
  // Open the DevTools.
   mainWindow.webContents.openDevTools();
 
 
   // My function ****************************
   setInterval(() => {
    os.cpuUsage(function(v){
      mainWindow.webContents.send('cpu',v*100);
      mainWindow.webContents.send('mem',os.freememPercentage()*100);
      mainWindow.webContents.send('total-mem',os.totalmem()/1024);
    });
  },1000);
};
 
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);
 
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit();
  }
});
 
app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow();
  }
});
 
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and import them here.

 

 

Interface utilisateur

Index.html

Dans le fichier html, importez d'abord l'électron et l'ipcRenderer. Vous pouvez recevoir le message en écoutant le nom du message. puis récupérez les données du gestionnaire d'événements. Je vais les mettre sur la console de développement.

<script>
  const electron = require('electron');
  const ipcRenderer = electron.ipcRenderer;
 
  ipcRenderer.on('cpu',(event,data) => {
    console.log('cpu % ' + data);
  });
  ipcRenderer.on('mem',(event,data) => {
    console.log('mem % ' + data);
  });
  ipcRenderer.on('total-mem',(event,data) => {
    console.log('total mem GB ' + data);
  });
</script>

 

 

Nous avons maintenant réussi à communiquer entre les processus principal et de rendu.

L'étape suivante consiste à travailler sur l'interface utilisateur.

 index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>CPU Monitor - Electron-App</title>
    <link rel="stylesheet" href="./index.css" />
    <link rel="icon" href="./favicon.ico" />
  </head>
  <body>
<main>
  <div class="box">
    <label>Now</p>
    <p id="now">-</p>
  </div>
  <div class="box">
    <label>CPU (%)</p>
    <p id="cpu">-</p>
  </div>
  <div class="box">
    <label>Free Mem (%)</p>
    <p id="mem">-</p>
  </div>
  <div class="box">
    <label>Total Mem (GB)</p>
    <p id="total-mem">-</p>
  </div>
</main>
<!-- SCRIPTS -->
<script src="./app.js"></script>
  </body>
</html>

 

app.js

const electron = require('electron');
const ipcRenderer = electron.ipcRenderer;
 
ipcRenderer.on('cpu',(event,data) => {
    console.log('cpu % ' + data);
    document.getElementById('cpu').innerHTML = data.toFixed(2);
  });
  ipcRenderer.on('mem',(event,data) => {
    console.log('mem % ' + data);
    document.getElementById('mem').innerHTML = data.toFixed(2);
  });
  ipcRenderer.on('total-mem',(event,data) => {
    console.log('total mem GB ' + data);
    document.getElementById('total-mem').innerHTML = data.toFixed(2);
  });
 
 
setInterval(() => {
    let now = new Date();
    let strDateTime = [[AddZero(now.getDate()),
        AddZero(now.getMonth() + 1),
        now.getFullYear()].join("/"),
        [AddZero(now.getHours()),
            AddZero(now.getMinutes()),
            AddZero(now.getSeconds())].join(":"),
        now.getHours() >= 12 ? "PM" : "AM"].join(" ");
        if (strDateTime != null) {
            console.log('now : ' + strDateTime);
            document.getElementById('now').innerHTML = strDateTime;
        }
  },1000);
 
  function AddZero(num) {
    return (num >= 0 && num < 10) ? "0" + num : num + "";
  }

 

Index.css

html {
  width: 100vw;
  height: 100vh;
}
body {
  font-family"Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  margin: autopadding: 1rem;
  width:100%;
  height: 100%;
  overflow: hidden;
  background: #333;
  display: flex;
  justify-content: center;
  align-items: center;
  color: #e0e0e0;
}
main{ margin: 0;padding:0;
  width:100%;height: 100%;
  display: flex;
  flex-wrap: wrap;}
.box {
  justify-content: center;
  flex: 1 1 40%;
  padding: 0 1rem;
}
.box:first-child {
  flex: 1 1 100%;
  margin-bottom: 1rem;
}
 
.box:not(:first-child) {
  flex: 1;
}
.box label {
  font-size: 1rem;
  font-weight: 400;
  color:rgb(255, 255, 255);
}
.box p, .box:first-child p {
  font-size: 2rem;
  font-weight: 600;
  color:rgb(226, 148, 32);
  padding: 0margin: 0;
}
.box:first-child p {
  font-size: 3rem;
}

 

Création d'un installateur

Pour ne pas à avoir à éxecuter de commande nous devons encapsuler notre web-app dans un exécutable ".exe" avec le programme d'installation. Electron Forge peut le faire facilement en exécutant simplement le script make.

npm run make

 

 

Votre application sera encapsulé dans un fichier exécutable sur votre machine.

La sortie sera dans le dossier "out" de votre projet. "\electron-app\my-cpu-app\out\make\squirrel.windows\x64"

Cependant, le programme d'installation de cette méthode permet une installation en un clic grâce à squirrel. Cependant cette installation se fait immédiatement, sans fenêtre de confirmation ou la possibilité à l'utilisateur de modifier le chemin d'installation.

electron-cpu-app-compile-squirrel

 

Nous pouvons donc utiliser un autre packageur appelé electron-builder.

npm install electron-builder --only=dev

 

 

Ensuite, nous ajouterons un paramètre de construction pour notre nouveau programme d'installation dans package.json. Nous allons d'abord changer le nom du produit. Puisque my-cpu-app est le nom de notre projet et nous ne voulons pas l'utiliser pour le vrai nom de l'application. Je vais donc le changer en "CPU Monitor"

Ensuite, créez un nouveau script pour exécuter le générateur d'électrons. alors maintenant, nous pouvons construire l'installation en tapant npm run build-installer.

{
  "name": "my-cpu-app",
  "productName": "CPU Monitor",
  "version": "1.0.0",
  "description": "My Electron application of CPU Monitoring",
  "main": "src/index.js",
  "scripts": {
    ...
    "build-installer": "electron-builder"
  },...
 

 

 

 

Pour installer la configuration de construction "build" dans le package.json. Nous devons ajouter un appID qui est le nom de notre projet et gagner pour la plate-forme de fenêtre, puis nous définirons la cible sur NSIS, qui est un type d'installateur que nous connaissons tous. Modifiez également l'affichage du nom de l'icône/de l'application dans le panneau de configuration. Si votre application doit s'exécuter en tant qu'administrateur, vous pouvez définir RequestExecutionLevel sur requireAdministrator (facultatif)Vous pouvez fournir un fichier license.txt si vous souhaitez l'afficher et le faire accepter par l'utilisateur avant l'installation. Je vais également définir l'option oneClick sur false et allowToChangeInstallationDirectory sur true afin que l'utilisateur puisse modifier le chemin d'installation.

  "build": {
      "appId": "my-cpu-app",
      "win": {
        "target": [
          "nsis"
        ],
        "icon": "src/favicon.png",
        "requestedExecutionLevel": "requireAdministrator"
      },
      "nsis": {
        "installerIcon": "src/favicon.ico",
        "uninstallerIcon": "src/favicon.ico",
        "uninstallDisplayName": "CPU Monitor",
        "license": "license.txt",
        "oneClick": false,
        "allowToChangeInstallationDirectory": true
      }
    },
{...}

 

 

{...},
  "dependencies": {
    "electron-squirrel-startup": "^1.0.0",
    "os-utils": "0.0.14"
  },
  "devDependencies": {
...
    "electron": "15.0.0",
    "electron-builder": "^22.6.1"
  }
 

 

 

Maintenant, Vous pouvez encapsuler votre application avec electron-buiilder

npm run build-installer

 

 

La sortie sera dans le dossier "dist" de votre projet. "\electron-app\my-cpu-app\dist"

electron-cpu-app-compile-electronbuilder