Comment exécuter et comstackr un fichier exécutable externe en utilisant Electron?

Par exemple, j’ai un cudaDeviceQuery binary cudaDeviceQuery qui renvoie une liste de périphériques au cudaDeviceQuery JSON. Voici un morceau de code:

 export default function cudaDeviceQuery(): Promise { const throwError = () => { throw new Error("Unfortunately your platform isn't yet unsupported"); }; const file = __DARWIN__ ? path.join(__dirname, 'darwin', 'cudaDeviceQuery') : __WIN32__ ? path.join(__dirname, 'win', 'cudaDeviceQuery.exe') : throwError(); const descriptor = spawn(file); return new Promise((resolve, reject) => { let outerData = ''; descriptor.stdout.on('data', data => { outerData += data; }); descriptor.on('close', () => { try { resolve(JSON.parse(outerData)); } catch (e) { reject(e); } }); }); } 

Mais lorsque j’utilise cette fonction du processus de rendu, __dirname est / , je reçois spawn /darwin/cudaDeviceQuery ENOENT erreur spawn /darwin/cudaDeviceQuery ENOENT . Quelle est la bonne façon de le générer dans dev envivroment et de l’intégrer à la production?

Une configuration webpack:

webpack.config.base.js :

 /** * Base webpack config used across other specific configs */ const webpack = require('webpack'); const path = require('path'); const getReplacements = require('./app/app-info').getReplacements; const { dependencies: externals } = require('./app/renderer/package.json'); module.exports = { module: { noParse: [path.join(__dirname, 'node_modules/ws')], rules: [ { test: /\.tsx?$/, use: [ { loader: 'babel-loader', }, { loader: 'ts-loader', }, ], exclude: /node_modules/, }, ], }, output: { path: path.join(__dirname, 'app', 'renderer'), filename: 'bundle.js', libraryTarget: 'commonjs2', }, // https://webpack.github.io/docs/configuration.html#resolve resolve: { extensions: ['.js', '.ts', '.tsx', 'json'], modules: [path.join(__dirname, 'app', 'renderer'), 'node_modules'], }, plugins: [new webpack.DefinePlugin(getReplacements())], externals: [...Object.keys(externals || {}), 'ws'], }; 

webpack.config.development.js :

 /** * Build config for development process that uses Hot-Module-Replacement * https://webpack.github.io/docs/hot-module-replacement-with-webpack.html */ const webpack = require('webpack'); const merge = require('webpack-merge'); const baseConfig = require('./webpack.config.base'); const getReplacements = require('./app/app-info').getReplacements; const port = process.env.PORT || 3000; module.exports = merge(baseConfig, { devtool: 'inline-source-map', entry: [ 'react-hot-loader/patch', `webpack-hot-middleware/client?path=http://localhost:${port}/__webpack_hmr&reload=true`, './app/renderer/index', ], output: { publicPath: `http://localhost:${port}/dist/`, }, module: { rules: [ // Css, SCSS, woff loaders are here ], }, plugins: [ // https://webpack.github.io/docs/hot-module-replacement-with-webpack.html new webpack.HotModuleReplacementPlugin(), new webpack.LoaderOptionsPlugin({ debug: true, }), ], // https://github.com/chentsulin/webpack-target-electron-renderer#how-this-module-works target: 'electron-renderer', }); 

webpack.config.electron.js :

 /** * Build config for electron 'Main Process' file */ const webpack = require('webpack'); const merge = require('webpack-merge'); const baseConfig = require('./webpack.config.base'); const getReplacements = require('./app/app-info').getReplacements; module.exports = merge(baseConfig, { devtool: 'source-map', entry: ['./app/main/index.ts'], // 'main.js' in root output: { path: __dirname, filename: './app/main/main.js', }, plugins: [ // Add source map support for stack traces in node // https://github.com/evanw/node-source-map-support // new webpack.BannerPlugin( // 'require("source-map-support").install();', // { raw: true, entryOnly: false } // ), ], /** * Set target to Electron specific node.js env. * https://github.com/chentsulin/webpack-target-electron-renderer#how-this-module-works */ target: 'electron-main', /** * Disables webpack processing of __dirname and __filename. * If you run the bundle in node.js it falls back to these values of node.js. * https://github.com/webpack/webpack/issues/2010 */ node: { __dirname: false, __filename: false }, }); 

Comme vous le voyez, j’utilise dev server pour remplacer des modules à chaud, c’est peut-être pour cette raison … J’ai server.js qui crée un serveur avec des scripts, puis je l’utilise depuis le processus principal. Voici server.js :

 /** * Setup and run the development server for Hot-Module-Replacement * https://webpack.github.io/docs/hot-module-replacement-with-webpack.html */ const argv = require('minimist')(process.argv.slice(2)); const { spawn } = require('child_process'); async function createMiddleware(port, configPath) { const express = require('express'); const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware'); const webpackHotMiddleware = require('webpack-hot-middleware'); const config = require(configPath); const app = express(); const comstackr = webpack(config); const PORT = process.env.PORT || port; const wdm = webpackDevMiddleware(comstackr, { publicPath: config.output.publicPath, stats: { colors: true, }, }); app.use(wdm); app.use(webpackHotMiddleware(comstackr)); const server = app.listen(PORT, serverError => { if (serverError) { return console.error(serverError); } console.log(`Listening at http://localhost:${PORT}`); }); process.on('SIGTERM', () => { console.log('Stopping dev server'); wdm.close(); server.close(() => { process.exit(0); }); }); } createMiddleware(3000, './webpack.config.development'); // A main renderer process createMiddleware(3010, './webpack.config.server'); // A backend for communicating between renderer and remote server if (argv['start-hot']) { spawn('npm', ['run', 'start-hot'], { shell: true, env: process.env, stdio: 'inherit', }) .on('close', code => process.exit(code)) .on('error', spawnError => console.error(spawnError)); } 

Un autre mot, je dois appeler la bibliothèque cudaDeviceQuery partir du processus de rendu électronique. J’utilise un electron-builder mais peu importe, je peux changer de constructeur.

Il y a deux choses. Si vous définissez __dirname: true dans la configuration de votre application Web, vous obtiendrez le chemin relative du fichier à partir de votre répertoire de contexte.

Si vous définissez __dirname: false __dirname aura le chemin complet.

Mode de développement

Vous avez deux options

  1. Définissez __dirname: true et concaténez-le avec os.cwd()
  2. Définissez __dirname: false et utilisez directement __dirname

Mode de production

  1. Définissez __dirname: true et utilisez os.cwd() .
  2. Définissez __dirname: true et utilisez process.resourcePath

Je préférerai 2 comme approche privilégiée en production

Ajoutez ceci dans package.json :

 "scripts": { "start": "electron .", "install": "electron-rebuild", "package-osx": "electron-packager . Node-RED --platform=darwin --arch=x64 -- out=build --overwrite", "package-mac": "electron-packager . --overwrite --platform=darwin --arch=x64 --prune=true --out=release-builds", "package-win": "electron-packager . electron-serialport --overwrite --asar=true --platform=win32 --arch=x64 --prune=true --out=release-builds --version-ssortingng.CompanyName=CE --version-ssortingng.FileDescription=CE --version-ssortingng.ProductName=\"CryptoApp\"", "package-linux": "electron-packager . electron-serialport --overwrite --asar=true --platform=linux --arch=x64 --prune=true --out=release-builds" }, "dependencies": { "electron-packager": "^12.1.0", "electron-prebuilt": "^1.4.13", } 

Si vous ne travaillez pas sous Windows, utilisez ce qui suit:

 "package-win": "electron-packager . electron-serialport --overwrite --asar=true --platform=win32 --arch=ia32 --prune=true --out=release-builds --version-ssortingng.CompanyName=CE --version-ssortingng.FileDescription=CE --version-ssortingng.ProductName=\"CryptoApp\"", 

Merci…