electron js中发生某些事件时如何执行节点命令window

How to execute node command when some event occur in electron js window

我正在制作一个有两个按钮的电子 js 应用程序。 我已经为它们分配了点击事件监听器。 当有人点击它们时,我想做的是分别增加或减少亮度。

我在 node.js 中构建了一个函数,如果我们 运行 使用 sudo 命令,它确实会增加亮度。

函数如下:

let fs = require("fs");

function inc() {
  var data = fs.readFileSync(
    "/sys/class/backlight/amdgpu_bl1/brightness",
    "utf-8"
  );

  var newData = parseInt(data) + 10;
  if (newData > 255) {
    newData = 255;
  } else if (newData < 0) {
    newData = 0;
  }
  newData = newData.toString();

  fs.writeFileSync(
    "/sys/class/backlight/amdgpu_bl1/brightness",
    newData,
    "utf-8"
  );
}

index.html代码是:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Clock App</title>
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <button onclick="incBright()">+</button>
    <button onclick="decBright()">-</button>
    <script src="script.js"></script>
  </body>
</html>

我想在有人点击'+'按钮时执行inc()函数! elctron js app window

谁能告诉我是否可以这样做。

我正在使用 linux

我对这东西一无所知

要在主线程和渲染线程之间进行通信,您需要熟悉 Electron 的 Inter-Process Communication and Context Isolation

此外,您还需要熟悉 Electron 的 ipcRenderer and ipcMain 模块。


关于亮度调整,您将希望通过使用 IPC 将该调整传达给主线程。要安全地与主线程通信,应该使用 preload.js 脚本。

preload.js 脚本已集成到应用程序的构建中 window,允许执行允许的操作。

下面是一个预加载脚本,它使用“通道名称”在主线程和渲染线程之间传递信息。

Is a good design decision not to implement concrete functions directly within your preload.js script. Instead, use you preload script as a gate keeper to only allow messages between threads. This will greatly simplify your preload script and separate your concerns.

下面是一个预加载脚本的示例,它可以满足您的要求,注意通道名称 brightness:incrementbrightness:decrement 的使用。您可以将这些频道名称重命名为任何您喜欢的名称。

preload.js(主线程)

// Import the necessary Electron components.
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// White-listed channels.
const ipc = {
    'render': {
        // From render to main.
        'send': [
            'brightness:increment',
            'brightness:decrement'
        ],
        // From main to render.
        'receive': [],
        // From render to main and back again.
        'sendReceive': []
    }
};

// Exposed protected methods in the render process.
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods.
    'ipcRender', {
        // From render to main.
        send: (channel, args) => {
            let validChannels = ipc.render.send;
            if (validChannels.includes(channel)) {
                ipcRenderer.send(channel, args);
            }
        },
        // From main to render.
        receive: (channel, listener) => {
            let validChannels = ipc.render.receive;
            if (validChannels.includes(channel)) {
                // Deliberately strip event as it includes `sender`.
                ipcRenderer.on(channel, (event, ...args) => listener(...args));
            }
        },
        // From render to main and back again.
        invoke: (channel, args) => {
            let validChannels = ipc.render.sendReceive;
            if (validChannels.includes(channel)) {
                return ipcRenderer.invoke(channel, args);
            }
        }
    }
);

现在我们的预加载脚本已经配置好了,让我们在构建应用程序时使用它 window。

此外,让我们监听这些消息通道,当检测到时,调用我们的 adjustBrightness 函数。

main.js(主线程)

const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronIpcMain = require('electron').ipcMain;

const nodeFs = require("fs");
const nodePath = require("path");

// Prevent garbage collection
let window;

function createWindow() {
    const window = new electronBrowserWindow({
        x: 0,
        y: 0,
        width: 800,
        height: 600,
        show: false,
        webPreferences: {
            nodeIntegration: false, // For safety, let's disable Node integration
            contextIsolation: true, // For safety, let's enable context isolation
            preload: nodePath.join(__dirname, 'preload.js') // Let's use our preload script
        }
    });

    window.loadFile('index.html')
        .then(() => { window.show(); });

    return window;
}

electronApp.on('ready', () => {
    window = createWindow();
});

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

electronApp.on('activate', () => {
    if (electronBrowserWindow.getAllWindows().length === 0) {
        createWindow();
    }
});

// Let's listen for messages to increment or decrement the brightness
electronIpcMain.on('brightness:increment', () => {
    adjustBrightness(10);
})

electronIpcMain.on('brightness:decrement', () => {
    adjustBrightness(-10);
})

// Function to adjust screen brightness
function adjustBrightness(adjustment) {
    let data = nodeFs.readFileSync('/sys/class/backlight/amdgpu_bl1/brightness', 'utf-8');

    let newData = parseInt(data) + adjustment;

    if (newData > 255) {
        newData = 255;
    } else if (newData < 0) {
        newData = 0;
    }

    newData = newData.toString();

    nodeFs.writeFileSync('/sys/class/backlight/amdgpu_bl1/brightness', newData, 'utf-8');
}

最后,让我们确保我们呈现的 html 在单击相应按钮时将消息发送到主线程。

index.html(渲染线程)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Clock App</title>
    </head>

    <body>
        <input type="button" id="incBrightness" value="+">
        <input type="button" id="decBrightness" value="-">
    </body>

    <script>
        document.getElementById('incBrightness').addEventListener('click', () => {
            window.ipcRender.send('brightness:increment');
        })

        document.getElementById('decBrightness').addEventListener('click', () => {
            window.ipcRender.send('brightness:decrement');
        })
    </script>
</html>