在electron中使用node-serialport的正确姿势

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在electron中使用node-serialport的正确姿势相关的知识,希望对你有一定的参考价值。

参考技术A

node-serialport 是一个让node可以访问电脑串口设备的原生模块,在electron环境下使用并不是简单的 npm install serialport 就能解决的事情。对于刚开始接触node的人来说,不折腾一番基本上是不可能的。如果不明就里的一次性安装成功,那下一次安装多半也需要折腾的。

折腾过程中,免不了在Google,百度,GitHub上掘地三尺找解决方案。

本文尽可能的详细介绍如何在electron中编译并使用seialport。这里使用的系统环境是win10,需要准备一下几个材料:

如果你的机器上没有安装过VS的话,并且后面不会使用VS的话,建议安装Visual Studio Build Tools即可。

在 使用 Node 原生模块 一文里介绍好几种使用原生模块的方法。这里介绍前面两种。

通过设置一些环境变量来实现npm的安装。为了方便,可以选择写个.bat文件来导入这些参数。

这里需要注意前两行的路径。

第一行是Visual Studio Build Tools安装后得到的一些批处理,主要是导入一些变量到cmd。
第二行是python的路径,如果电脑有多个python的话,建议通过set的方式导入到本次命令行。
剩下的都是electron相关的参数。target版本号可以在首页里面找。

到这里,可以尝试执行 npm install serialport 来安装serialport了。如果安装过程不会报错,则基本上OK了。

如果报错了,看一下报错信息。

如果是有404或者GET请求失败,则是网络问题。

另外,如果先前npm报错过,建议删除node_modules文件夹重新 npm install 。

使用rebuild( npm install electron-rebuild --save-dev )来构建serialport不需要设置太多变量,但是下面两行少不了的。

接着执行 npm install 安装各种依赖。安装完后,执行 .\\node_modules\\.bin\\electron-rebuild.cmd 重新编译一下,serialport才能在electron里面使用。

编译过程中可以会出错,比如使用了python3或者msbuild版本错误等一堆乱七八糟的错误。具体看错误日志定位问题才能解决。

具体使用的看下面

在 Electron 应用程序中使用 console.log()

【中文标题】在 Electron 应用程序中使用 console.log()【英文标题】:Using console.log() in Electron app 【发布时间】:2015-10-23 21:53:00 【问题描述】:

如何在我的 Electron 应用中将数据或消息记录到控制台?

这个非常基本的 hello world 默认打开开发工具,我无法使用console.log('hi')。 Electron 有替代品吗?

ma​​in.js

var app = require('app');
var BrowserWindow = require('browser-window');

require('crash-reporter').start();

var mainWindow = null;

app.on('window-all-closed', function() 
  // Mac OS X - close is done explicitly with Cmd + Q, not just closing windows
  if (process.platform != 'darwin') 
    app.quit();
  
);

app.on('ready', function()
  mainWindow = new BrowserWindow( width: 800, height: 600);

  mainWindow.loadUrl('file://' + __dirname + '/index.html');

  mainWindow.openDevTools();

  mainWindow.on('closed', function()
    mainWindow = null;
  );
);

【问题讨论】:

对于偶然发现此问题的人来说只是一个小提示:<webview> 标签中也支持开发工具,也可以通过文档中的 openDevTools() 方法here 【参考方案1】:

console.log 有效,但它记录到的位置取决于您是从主进程还是渲染器进程调用它。

如果您从渲染器进程(即包含在您的 index.html 文件中的 JavaScript)调用它,它将被记录到开发工具窗口中。

如果您从主进程调用它(即在main.js 中),它将以与在 Node 中相同的方式工作 - 它将登录到终端窗口。如果您使用 electron . 从终端启动 Electron 进程,您可以在主进程中看到您的 console.log 调用。

【讨论】:

我可以console.log()从渲染进程到主进程吗? @FandiSusanto,您可以使用 ipcRenderer 模块向您的主进程发送消息,然后在其中发送 console.log()。 生产模式下的内容,主进程中的`console.log()`会做什么 @JimmyObonyoAbor 要将控制台附加到 production 电子应用程序并在终端中获取控制台输出,请在终端./path/to/release/MyProgram.app/Contents/MacOS/MyProgram 中运行以下命令。这将运行二进制 MyProgram 并允许您在终端中查看进程 console.log 事件。 如何通过app.relaunch()app.exit(0) 重置应用程序后仍将内容记录到终端???【参考方案2】:

你也可以在windows中添加环境变量:

ELECTRON_ENABLE_LOGGING=1

这会将控制台消息输出到您的终端。

【讨论】:

在设置此环境变量之前,我没有在控制台中看到任何消息。 docs 说应该设置为true 并将其设置为true“将 Chrome 的内部日志打印到控制台”,这不是 OP 想要的。 @pushkin 它也适用于ELECTRON_ENABLE_LOGGING=1。至于OP想要什么,那又是什么?看看下面gist看看效果。 ELECTRON_ENABLE_LOGGING=1 添加到哪个文件? @Still_learning 您将其设置为环境变量。所以从 Windows 命令行 set ELECTRON_ENABLE_LOGGING=true【参考方案3】:

还有另一种从渲染器进程内部登录到控制台的方法。鉴于这是 Electron,您可以访问 Node 的本机模块。这包括console 模块。

var nodeConsole = require('console');
var myConsole = new nodeConsole.Console(process.stdout, process.stderr);
myConsole.log('Hello World!');

从渲染器进程内部运行此代码时,您将在运行 Electron 的终端中获得 Hello World!

有关console 模块的更多文档,请参阅https://nodejs.org/api/console.html。

【讨论】:

只有当我在 main.js 中完全不使用 console.log 时它才对我有用【参考方案4】:

另一种可能性是使用remote.getGlobal(name) 访问主进程控制台:

const con = require('electron').remote.getGlobal('console')
con.log('This will be output to the main process console.')

【讨论】:

这很好用,但我们如何才能捕获整个控制台输出;即——无需调用特殊函数;这样也会输出异常和错误? Derrick:尝试设置环境变量ELECTRON_ENABLE_LOGGING=1(见deejbee的回答) 我正在尝试在后台脚本中使用扩展程序,但它不起作用,不清楚原因。 (后台脚本作为后台窗口加载,基本上)【参考方案5】:

添加到 M. Damian 的答案,这是我设置它的方式,以便我可以从任何渲染器访问主进程的控制台。

在您的主应用程序中,添加:

const electron = require('electron');
const app = electron.app;
const console = require('console');
...
app.console = new console.Console(process.stdout, process.stderr);

在任何渲染器中,您都可以添加:

const remote = require('electron').remote;
const app = remote.app;
...
app.console.log('This will output to the main process console.');

【讨论】:

【参考方案6】:
process.stdout.write('your output to command prompt console or node js ')

【讨论】:

虽然这段代码可能有助于解决问题,但它并没有解释为什么和/或如何回答问题。提供这种额外的背景将显着提高其长期价值。请edit您的答案添加解释,包括适用的限制和假设。【参考方案7】:

可以使用 npm 包 electron-log https://www.npmjs.com/package/electron-log

它将在您的本机操作系统日志中记录您的错误、警告、信息、详细、调试、愚蠢的输出。

var log = require('electron-log');

log.info('Hello, log');
log.error('Damn it, an error');

【讨论】:

【参考方案8】:

很抱歉提出一个旧线程,但这是“如何将 console.log 输出到终端”(或类似搜索)的最高结果。

对于希望对终端输出内容有更多控制权的人,您可以像这样使用 webContents.on('console-message'):

mainWindow.webContents.on('console-message', (event, level, message, line, sourceId) => 
      console.log(message + " " +sourceId+" ("+line+")");
);

见:

webContents Documentation

webContents entry on BrowserWindow docs

【讨论】:

【参考方案9】:

这是 cscsandy5 对一些附加信息的回答的后续,信息来自here

process.stdout.write('your output to command prompt console or node js ')

此代码非常适合仅将简单的调试消息输出到您启动电子应用程序的终端窗口,并且是console.log 构建的基础。

这是一个 jQuery 脚本的示例 sn-p(基于 tutorialspoint 电子教程),每次按下按钮时都会向终端写 hello(警告:您需要在输出字符串中添加自己的换行符! )

let $ = require('jquery')
var clicks = 0;

$(function() 
    $('#countbtn').click(function() 
        //output hello <<<<<<<<<<<<<<<<<<<<<<<
        process.stdout.write('hello')

        $('#click-counter').text(++clicks);
    );

    $('#click-counter').text(clicks);
);

【讨论】:

【参考方案10】:

这是我用的:

let mainWindow // main window reference, you should assign it below 'mainWindow = new BrowserWindow'

function log(...data) 
  mainWindow.webContents.executeJavaScript("console.log('%cFROM MAIN', 'color: #800', '" + data + "');");

使用示例(同console.log):

log('Error',  msg: 'a common log message' )
log('hello')

来源:logger.js 文件中的https://github.com/fuse-box/fuse-box-electron-seed/tree/master/src/main,在这里你可以看到一个真实的用例。

【讨论】:

数据需要编码(作为 JSON 字符串?)以避免 JS 代码注入。【参考方案11】:

经过一番调查,我的理解是:

代码

(1) main.js


const createPyProc = () => 
  console.log('In createPyProc')
...
  console.log('scriptStart=%s', scriptStart)
...
  console.log('scriptOther=%s', scriptOther)
...


...

let mainWindow = null

const createWindow = () => 
  mainWindow = new BrowserWindow(
    
      width: 1024,
      height: 768,
      webPreferences: 
        nodeIntegration: true,
      
    
  )
  mainWindow.loadURL(require('url').format(
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file:',
    slashes: true
  ))
  mainWindow.webContents.openDevTools()

  mainWindow.on('closed', () => 
    mainWindow = null
  )

...

注意:使用openDevTools打开Electron Dev Tools

(2) 渲染.js

const zerorpc = require("zerorpc")
...
    console.log("clientStart %d server is ready", PORT_START)
...
)

(3) render.js 被调用者:index.html

<!DOCTYPE html>
<html>
...
  <script>
    require('./renderer.js')
  </script>
</html>

console.log

输出逻辑

两个进程及其console.log输出: main process = NodeJS process = 这里Electron UI process -> console.log in main.js 将输出日志到这里 render process -> console.log in render.js 将输出日志到这里

截图示例

DEBUG=开发模式 运行./node_modules/.bin/electron . Production=Release模式=eletron-builder打包的xxx.app 运行/path_to_your_packaged_mac_app/xxx.app/Contents/MacOS/yourBinaryExecutable 添加export ELECTRON_ENABLE_LOGGING=true,render.jsconsole.log ALSO输出到main process终端

【讨论】:

【参考方案12】:

console.log() 可以很好地进行调试。由于electron 构建在浏览器之上,它具有DevTools 支持,您可以使用devtools 进行调试。但是,console.log() 方法存在歇斯底里的行为。当您从电子应用程序的main process 调用console.log() 时,它将输出到您刚刚启动应用程序的终端窗口,当您从renderer process 调用它时,它将输出到DevTools 控制台。

【讨论】:

【参考方案13】:

Alex Warren wrote 的一切都是真的。这里重要的是 Electron 是如何启动的。如果您在 package.json 文件中使用标准脚本,它将不起作用。为了使console.log() 工作,用这个新脚本替换旧脚本。

旧的:

"scripts": 
    "start": "electron ."

新的:

"scripts": 
    "start": ".\\node_modules\\electron\\dist\\electron.exe ."

现在所有console.log() 呼叫也显示在终端中。

【讨论】:

你拯救了我的一天!!!在 win server 2012 上,这是使 console.log 工作的唯一方法!【参考方案14】:

有了这个你可以使用主浏览器窗口的开发者工具来查看日志

    function logEverywhere(s) 
        if (_debug === true) 
            console.log(s);
            // mainWindow is main browser window of your app
            if (mainWindow && mainWindow.webContents) 
                mainWindow.webContents.executeJavaScript(`console.log("$s")`);
            
        
    

例如logEverywhere('test') 将在主浏览器窗口的开发者工具的控制台面板中输出// test

您可能需要增强此方法以接受多个参数(您可以使用 es6 的扩展运算符来完成)

【讨论】:

【参考方案15】:

嗯,这是 2019 年,我不敢相信在上面的所有答案中都没有人提到这个技巧。 好的,那么,直接从主目录直接登录到浏览器控制台怎么样? 我在这里提供了答案:https://***.com/a/58913251/8764808 看看吧。

【讨论】:

谢谢@Wale!你介意内联你的答案吗?我不介意链接到另一个问题,但是这里的很多模组都对交叉链接答案感到恼火,即使是这样。 我真的很想这样做,但是我上次尝试这样做时,我因重复答案而受到谴责。【参考方案16】:

我正在进行的一个项目使用的是electron-react-boilerplate。这有electron-devtools-installer@2.4.4,它以某种方式通过cross-unzip 导致进程以Error: Exited with code 9 崩溃。

升级到electron-devtools-installer@3.1.1,因为proposed in electron-react-boilerplate@v2.0.0 解决了它,所以我的console.logconsole.error 等语句按预期工作。

【讨论】:

以上是关于在electron中使用node-serialport的正确姿势的主要内容,如果未能解决你的问题,请参考以下文章

使用 Electron 在 Angular 2 应用程序中访问文件系统

在 Electron 应用程序中使用 console.log()

如何在 Electron 中使用 node_modules?

如何在 Electron 中使用 node_modules?

使用electron-builder打包时下载electron失败解决方案

Electron 使用Pepper Flash插件