preface

We had a course design for operating systems, and it was interesting to see how to implement a task manager based on the Proc file system. At the beginning of the preparation of c++ to write, later wrote a little, just know overestimated their c++ level…. , and then came up with the idea of implementing a task manager using Node + Electron. In this way, on the graphical interface, you can use HTML+CSS to write, the amount of tasks down all of a sudden!

Proc file system introduction

The /proc file system is a virtual file system that allows a new way to communicate between Linux kernel Spaces and users. In the /proc file system, we can read and write virtual files as a means of communicating with entities in the kernel, but unlike normal files, the contents of these virtual files are created on the fly.

Proc file system documentation

Electron is introduced

A cross-platform desktop application that uses JavaScript, HTML and CSS

Electron document

The preparatory work

Node.js needs to be installed. We recommend that you install the latest available LTS or Current version

To check that Node.js is installed correctly, type the following command on your terminal:

node -v
npm -v
Copy the code

Begin to build

mkdir electron-app && cd electron-app
npm init -y
npm i --save-dev electron
Copy the code

Then there should be a directory structure

|-- main.js
|-- package.json
|-- node_modules
|-- config
|-- tem
|-- utils
Copy the code

Modify the contents of package.json

"main": "main.js"."scripts": {
  	"start": "electron .",},Copy the code

Content Introduction

  • /utils/event.js
// It is mainly used to do event distribution, according to different events trigger different tasks
const EventEmitter = require('events');

class MyEmitter extends EventEmitter {}const Emitter = new MyEmitter();

module.exports = {
  Emitter
}
Copy the code
  • /utils/index.js
.// All functions are similar to this function, which is to read the corresponding file in // proc. The file is in memory, updated in real time, and records the corresponding information of the operating system
/ * * *@description Get information for each process */
function getProcessInfo() {
  const ProcesssInfos = fs.readdirSync('/proc');
  const processes = []
  ProcesssInfos.forEach(item= > {

    let finallPath = path.join('/proc', item)
    let stat = fs.lstatSync(finallPath)
    if (stat.isDirectory && !isNaN(Number(item))) {
      const processinfo = fs.readFileSync(path.join(finallPath, '/status'), { encoding: 'utf8'}) processes.push(... stringToJson(processinfo))// stringToJson writes a string parsing method of its own}})returnprocesses; }...Copy the code
  • /utils/render.js
./ * * *@description deal with the processinfopage render
 */

function renderProcessInfo(processInfo) {

  let template = ` 
      
NAME PID STATE MEMORY
<% processInfo.forEach(item => {%>
> <%= item.Name%> <%= item.Pid%> <%= item.State%> <%= KBToMB(item["VmRSS"])%>
<%}) %>
`
template = ejs.render(template, { processInfo, KBToMB }) returntemplate; }... The method here is to use EJS to parse the template and then add it to the corresponding interfaceCopy the code
  • /config/config.js
const { Emitter } = require('.. /utils/events')
// Configure the electron menu
let MenuItems = [
  .....
]

// Echarts configuration
function getMemoryOrSawpOption(data) {
  return option = {
    ......
  };
}
// Echarts configuration
function getReceiveOrSendOption(data = 0, type) {
  letoption = { ..... }}Copy the code
  • /tem/**

Everything here is a corresponding interface that displays different information

  • main.js
const { app, BrowserWindow, Menu, MenuItem } = require('electron')
const { MenuItems } = require('./config/config')
const { Emitter } = require('./utils/events')


function createWindow() { // Create a window instance
  const win = new BrowserWindow({
    width: 800.height: 600.webPreferences: {
      nodeIntegration: true}})const items = MenuItems.map(item= > {
    return new MenuItem(item)
  })

  const menu = new Menu();
  items.forEach(item= > {
    menu.append(item)
  })
  // Set the menu
  win.setMenu(menu)

  win.loadFile('./tem/source/index.html')
  win.webContents.openDevTools();


  // Listen for different event feeling button clicks to load different interface
  
  // source page
  Emitter.on('source'.function () {
    win.loadFile('./tem/source/index.html');
  })

  // memory page
  Emitter.on('innerMemory'.function () {
    win.loadFile('./tem/innermemory/index.html')})// informatin page
  Emitter.on('information'.function () {
    win.loadFile('./tem/versionInfomation/index.html')})// disk infomation
  Emitter.on('disk'.function () {
    win.loadFile('./tem/diskInformation/index.html')
  })

  Emitter.on('process'.function () {
    win.loadFile('./tem/process/index.html')

  })
}

app.whenReady().then(createWindow)

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

app.on('activate'.() = > {
  if (BrowserWindow.getAllWindows().length === 0) {
    createWindow()
  }
})

Copy the code

Results show

Resource information

Memory information

Process information

Disk information

System information

packaging

I am not very clear about packaging myself, you can do your own research, I will list my packaging configuration

  "build": {
    "appId": "XXXX"."productName": "XXXX"."directories": {
      "output": "build"
    },
    "linux": {
      "target": [
        "deb"]."icon": "./icon.png"."synopsis": "simple"."maintainer": ".deb"}}Copy the code

Write in the last

I am not very good at Electron either, I can only say that I have a superficial understanding of it, I just wrote it after glancing at the document temporarily in order to write the GRAPHICAL interface, there are still many mistakes in the project, I hope you don’t criticize me… If anything I write is helpful to you, please give my Github a star

The project address