【问题标题】:Electron + Ionic + child_process电子 + 离子 + child_process
【发布时间】:2021-11-25 01:56:30
【问题描述】:

我正在构建一个在 Windows 上运行的电子应用程序来移动机器人。 (控制设备必须是客户要求的窗口)它内置在带有打字稿的 Ionic 中,我正在尝试创建一个桌面解决方案,该解决方案具有运行一些 .exe 文件以在一些预定义的动作中移动机器人的功能。它们是由另一个人制作的一组 .exe 文件,从 shell 运行时它们工作正常。那些 exe 文件确实会关闭/打开灯光、移动手臂等……现在这些 exe 文件可以正常工作,它们都在 C:\botcontrol\ 文件夹中。

我一直在努力使用 node 的 child_process 以便能够从一个简单的界面运行所有这些 exe 文件。我的问题是我无法以任何方式包含child_process,而不会出现控制台错误t(...).execFile is not a function

我已经用各种语言在互联网上挖掘了两天关于如何在 typescript angular 7 应用程序中包含 child_process 节点模块的问题,但我真的被这个问题困住了,我不知道如何解决它没有得到上面被诅咒的错误。我尝试添加到 tsconfig:

  "map": {
    "child_process": "@node/child_process"
  }

和许多其他 webpack 配置尝试,但没有一个对我有用。

现在我需要添加“child_process”,这样当我运行服务时,我可以像这样导入它:

import { exec,execFile} from "child_process";
...

import * as cp from "child_process";
...

我读到我需要在 SystemJS 或 webpack 配置中添加要导出的模块,但我在我的项目中没有找到类似的配置。

我的依赖在 package.json 中:

...
 "dependencies": {
    "@angular/common": "~8.1.2",
    "@angular/compiler": "~8.1.2",
    "@angular/core": "~8.1.2",
    "@angular/forms": "~8.1.2",
    "@angular/platform-browser": "~8.1.2",
    "@angular/platform-browser-dynamic": "~8.1.2",
    "@angular/router": "~8.1.2",
    "@ionic-native/core": "^5.14.0",
    "@ionic-native/splash-screen": "^5.14.0",
    "@ionic-native/status-bar": "^5.14.0",
    "@ionic/angular": "^4.9.1",
    "@ionic/storage": "^2.2.0",
    "@ngx-translate/core": "^11.0.1",
    "@ngx-translate/http-loader": "^4.0.0",
    "cordova-sqlite-storage": "^3.3.0",
    "core-js": "^2.5.4",
    "electron-json-storage": "^4.1.8",
    "ng-connection-service": "^1.0.4",
    "rxjs": "^6.5.3",
    "simple-keyboard": "^2.26.4",
    "tslib": "^1.9.0",
    "wine": "^0.9.8",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-devkit/architect": "~0.801.2",
    "@angular-devkit/build-angular": "~0.801.2",
    "@angular-devkit/core": "~8.1.2",
    "@angular-devkit/schematics": "~8.1.2",
    "@angular/cli": "~8.1.2",
    "@angular/compiler": "~8.1.2",
    "@angular/compiler-cli": "~8.1.2",
    "@angular/language-service": "~8.1.2",
    "@ionic/angular-toolkit": "~2.0.0",
    "@types/jasmine": "~3.3.8",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "^8.10.54",
    "codelyzer": "^5.1.1",
    "electron": "^6.0.10",
    "electron-installer-dmg": "^3.0.0",
    "electron-packager": "^14.0.6",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.1",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.0",
    "protractor": "~5.4.0",
    "ts-node": "~7.0.0",
    "tslint": "~5.15.0",
    "typescript": "~3.4.3"
  },
...

有人可以帮帮我吗?将不胜感激:)

【问题讨论】:

    标签: ionic-framework webpack electron child-process


    【解决方案1】:

    如果您使用@capacitor-community/electron 平台来构建您的应用程序,您必须考虑以下几点:

    • Electron 使用两种进程类型,主进程渲染进程(查找更多信息here
    • 渲染器进程基本上是一个网络浏览器,它不能使用诸如child_process之类的原生功能,而主进程可以
    • 渲染器进程可以与主进程通信,更多信息here
    • 您的 ionic/angular 应用被构建为作为渲染器进程运行

    一种可能的解决方案:

    从渲染进程(角度)向主进程(电子)发送消息,以使主进程运行可执行文件并将输出返回给渲染进程(又名黑魔法)。

    怎么做?

    创建主进程处理程序

    修改文件YOUR_PROJECT_DIR/electron/src/index.ts

    添加导入:

    import {ipcMain} from 'electron';
    import {execFileSync} from 'child_process';
    

    在文件的和处添加事件处理程序:

    ipcMain.handle('execCommand', (event, arg) => {
      //this will handle an event called 'execCommand' triggered from the renderer process
      let cmdRes = execFileSync("./path-to-file.exe", [], {encoding: 'utf8'});
      //cmdRes contains the file execution output
      return cmdRes;
    });
    

    ipcRenderer 暴露给 ionic/angular 应用程序的主要上下文

    修改文件YOUR_PROJECT_DIR/electron/src/preload.ts

    添加这个:

    const { contextBridge, ipcRenderer } = require('electron');
    contextBridge.exposeInMainWorld('electron', {
      ipc: { ...ipcRenderer }
    });
    

    安全问题:用户可以打开开发者工具并修改 javascript 代码以调用带有恶意内容的事件,这在本地环境中不是真正的问题,但它可能与远程资源有关。

    从 Angular 应用程序与主进程通信

    假设您在 ionic/angular 页面中:

    callExecutable() {
        (<any>window).electron.ipc.invoke('execCommand').then(
          res=>console.log(res) //res contains the command output from the main process
        );
    }
    

    通过这种方式,您可以为每个必须调用的.exe 文件创建一个事件处理程序,并为每个处理程序创建一个角度服务.invoke()

    刚刚测试过,它可以与ionic 版本6.18.1@capacitor-community/electron 版本7.5.6 一起使用

    【讨论】:

    • 欢迎来到 Stack Overflow 社区,Roberto。这是一个有用的第一个答案,具有令人钦佩的细节水平。继续努力。
    • @JeremyCaney 谢谢!这么多年过去了,能第一次回答真是太好了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-06
    • 2020-08-10
    • 1970-01-01
    • 2021-02-18
    • 2016-08-04
    • 1970-01-01
    • 2022-12-08
    相关资源
    最近更新 更多