MoloF Asked:2022-01-04 03:56:22 +0000 UTC2022-01-04 03:56:22 +0000 UTC 2022-01-04 03:56:22 +0000 UTC 如何为 CLI 版本的可执行文件创建 GUI? 772 有一个包gifski,它有一个CLI版本windows,要简单GUI,以免在终端输入命令。 NodeJS你如何构建一个应用程序来Electron访问这个文件并执行命令? 如何正确制定您的搜索问题google?我不知道该如何提问 node.js 1 个回答 Voted Best Answer nörbörnën 2022-01-05T02:02:36Z2022-01-05T02:02:36Z 演示应用源https://github.com/norbornen/electron-terminal-command-wrapper 创建一个运行控制台实用程序的电子应用程序非常简单! 使用任何电子应用程序骨架或自己制作: package.json { "name": "electron-terminal-command-wrapper", "version": "1.0.0", "main": "src/main/index.js", "license": "MIT", "keywords": [ "electron", "command line", "wrapper" ], "scripts": { "rebuild": "electron-rebuild", "start": "electron . --enable-logging", "dev": "NODE_ENV=development npm run start", "build": "echo 'dummy script'", "electron-build": "yarn build && electron-builder", "build:app": "yarn electron-build --dir", "build:all": "yarn electron-build build -mwl", "build:mac": "yarn electron-build build --mac", "build:linux": "yarn electron-build build --linux", "build:windows": "yarn electron-build build --windows --x64" }, "dependencies": { "electron-is-dev": "^1.2.0", "execa": "^5.0.0" }, "devDependencies": { "@types/electron": "^1.6.10", "@types/electron-is-dev": "^1.1.1", "@types/node": "^14.14.19", "electron": "^11.1.1", "electron-builder": "^22.9.1", "electron-rebuild": "^2.3.4", "eslint": "^7.17.0", "eslint-config-airbnb-base": "^14.2.1", "eslint-plugin-import": "^2.22.1" }, "build": { "appId": "org.dev.electron-terminal-command-wrapper", "productName": "etcmdwrapper", "artifactName": "${productName}.${ext}", "directories": { "output": "release" }, "files": [ "src/**/*" ], "win": { "target": [ "portable" ] }, "linux": { "target": [ "deb", "AppImage" ], "category": "Development" } } } 您编写main-part,应用程序启动器: const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('path'); const isDev = require('electron-is-dev'); /** @type {BrowserWindow} */ let win; function createMainWindow() { win = new BrowserWindow({ width: 600, height: 600, webPreferences: { nodeIntegration: true, } }); const filepath = path.resolve(__dirname, '../render/index.html'); win.loadURL(`file://${filepath}`); if (isDev) { win.webContents.openDevTools(); } win.once('closed', () => { win = null; }); } app.on('ready', () => { createMainWindow(); }); app.on('window-all-closed', () => { if (process.platform !== 'darwin') { app.quit(); } }); 你编写一个可以与 -th 通信的render-component :ipcmain <!DOCTYPE html> <html lang="en"> <head> <title>Terminal Command Run Electron Wrapper</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script type="text/javascript"> const { ipcRenderer } = require('electron'); const CHANNEL_NAME = 'channelCmd'; ipcRenderer.on(CHANNEL_NAME, (event, data) => { const el = document.getElementById('console'); el.innerText = data; }); function runIt(ev) { ev.preventDefault(); const formEl = document.getElementById('exampleForm'); const formData = new FormData(formEl); const command = (formData.get('command_command') || '').trim(); const options = (formData.get('command_options') || '').trim(); const argument = (formData.get('command_argument') || '').trim(); if (/\S/.test(command)) { const data = { command }; if (/\S/.test(options)) { data.options = options; } if (/\S/.test(argument)) { data.argument = argument; } ipcRenderer.send(CHANNEL_NAME, data); } } </script> </head> <body style="background: white"> <h2>Terminal Command Run Electron Wrapper</h2> <div> <form id="exampleForm" onsubmit="return false"> <div style="margin: 16px 0;"><input type="text" name="command_command" placeholder="command" style="padding: 5px;"></div> <div style="margin: 16px 0;"><input type="text" name="command_options" placeholder="command options" style="padding: 5px;"></div> <div style="margin: 16px 0;"><input type="text" name="command_argument" placeholder="command arguments" style="padding: 5px;"></div> <div style="margin: 16px 0;"> <button onclick="runIt(event)">Run command</button> <button type="reset">Reset</button> </div> </form> </div> <hr> <pre id="console" style="padding: 10px; background-color: #eeeeee;"></pre> </body> </html> 现在是最重要的部分,运行命令。 因为我对 gifski 一无所知,所以我为任何终端命令(用于 linux/macos)制作了一个启动器: const execa = require('execa'); ... app.on('ready', () => { createMainWindow(); initIpc(); }); ... function initIpc() { ipcMain.on('channelCmd', async (event, args) => { const { command, options, argument } = typeof args === 'string' ? JSON.parse(args) : args; try { const { stdout, stderr } = await execa(command, [options, argument].filter((x) => typeof x === 'string' && /\S/.test(x))); console.log(stdout); console.log(stderr); event.reply('channelCmd', stdout || stderr); } catch (err) { console.log(err); event.reply('channelCmd', err.stack || err.message); } }); } 可以通过child_process.spawn或child_process.exec,但我采用了同一个 Sindre Sorhus(gifski 的作者(但不是转换算法)的作者)的execa包来简化我的生活,而不是编写处理程序表。 通常,您只需要学习如何将 gifski 放在那里并滑出选项和参数即可运行。 Bloop 和瞧
演示应用源https://github.com/norbornen/electron-terminal-command-wrapper
创建一个运行控制台实用程序的电子应用程序非常简单!
package.jsonmain-part,应用程序启动器:render-component :ipcmain因为我对 gifski 一无所知,所以我为任何终端命令(用于 linux/macos)制作了一个启动器:
可以通过child_process.spawn或child_process.exec,但我采用了同一个 Sindre Sorhus(gifski 的作者(但不是转换算法)的作者)的execa包来简化我的生活,而不是编写处理程序表。
通常,您只需要学习如何将 gifski 放在那里并滑出选项和参数即可运行。
Bloop 和瞧