电子 + 离子 + 子进程

App*_*pha 1 child-process ionic-framework webpack electron

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

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

我已经在互联网上用各种语言挖掘了两天关于如何将child_process节点模块包含在打字稿角度7应用程序中,但我真的坚持这个,我不知道如何解决它而不得到该诅咒的错误多于。我尝试添加到 tsconfig:

  "map": {
    "child_process": "@node/child_process"
  }
Run Code Online (Sandbox Code Playgroud)

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

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

import { exec,execFile} from "child_process";
...
Run Code Online (Sandbox Code Playgroud)

或者

import * as cp from "child_process";
...
Run Code Online (Sandbox Code Playgroud)

我读到一些内容说我需要添加要在 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"
  },
...
Run Code Online (Sandbox Code Playgroud)

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

小智 5

如果您使用该@capacitor-community/electron平台构建应用程序,则必须考虑以下事项:

  • Electron 使用两种进程类型,主进程渲染器进程(在此处查找更多信息)
  • 渲染器进程基本上是一个 Web 浏览器,无法使用本机功能,例如child_process主进程可以
  • 渲染器进程可以与主进程通信,更多信息请参见此处
  • 您的离子/角度应用程序被构建为作为渲染器进程运行

一个可能的解决方案:

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

如何?

创建主进程处理程序

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

添加导入:

import {ipcMain} from 'electron';
import {execFileSync} from 'child_process';
Run Code Online (Sandbox Code Playgroud)

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

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;
});
Run Code Online (Sandbox Code Playgroud)

接触ipcRenderer离子/角度应用程序的主要背景

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

添加这个:

const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electron', {
  ipc: { ...ipcRenderer }
});
Run Code Online (Sandbox Code Playgroud)

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

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

假设您位于离子/角度页面内:

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

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

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