如何从不同的文件访问Electron JS中的变量,点击按钮后?

qfe3c7zg  于 2023-05-21  发布在  Electron
关注(0)|答案(1)|浏览(283)

我想知道如何从Electron JS中的不同文件访问变量。当我运行应用程序时,我想通过输入字段选择一个文件路径。它的工作原理。点击按钮后(并已事先选择的路径),我想发送此路径到另一个文件中的函数。
我尝试导出路径,但不起作用。请帮帮我我正在附加文件main.js和algorithm.js。我想在点击按钮时将结果从main.js导入algorithm.js。

/*This is algorithm.js*/
/*const { path } = require('main.js')

function getPath(path) {
    document.getElementById("toinject").innerHTML = path;
    console.log(path)

}*/

var fs = require("fs");
const readline = require('readline');
async function processLineByLine() {
    var writeStream = fs.createWriteStream("output.txt");
    const fileStream = fs.createReadStream('./kat.txt');

    const rl = readline.createInterface({
        input: fileStream,
        crlfDelay: Infinity
    });
       
    for await (const line of rl) {
        // Each line in input.txt will be successively available here as `line`.
        console.log(`Line from file: ${line}`);
        var new_line = deletefromBracket(line)
        writeStream.write(new_line + "\n");
    }
    writeStream.end();
    }

function deletefromBracket(str) {
    var indexOfLeftBracket = str.indexOf('(')
    str = str.substring(0, indexOfLeftBracket-1)
    return str;
}
/*This is main.js from electron*/
const { app, BrowserWindow, dialog, ipcMain } = require('electron')
const path = require('path')
let win;
function createWindow () {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

  win.loadFile('index.html')
}

app.whenReady().then(() => {
  createWindow()

  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow()
    }
  })
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

app.on('activate', function() {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (win === null) createWindow()
})

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
ipcMain.on('select-dirs', async (event, arg) => {
  const result = await dialog.showOpenDialog(win, {
    properties: ['openFile']
  })
  console.log('directories selected', result.filePaths)
  let path = result.filePaths;
  module.exports = { path };
})
pkbketx9

pkbketx91#

要在Electron渲染之间移动数据,您需要使用IPC (Inter-Process Communication)preload.js脚本。在已处理的变量之间导出和导入变量不起作用。
详细阅读下面的主题将帮助您了解Electron应用程序如何在进程之间进行通信,在本例中是主进程和两个渲染进程。

关于你的问题,你的目标是:
1.从渲染进程向主进程发送信号以打开文件对话框。
1.从主进程向其他渲染进程发送信号,沿着选定的路径。
main.js文件中,不需要使用async/await,因为我们可以直接将对话框的(承诺的)输出直接导入IPC方法(与第二个渲染进程通信)。
请参阅下面的最小可重复示例,了解如何在进程之间进行通信以及如何使用preload.js脚本。
PS:如果preload.js脚本的功能很难理解,请参阅this SO Answer,它提供了一种不同类型的方法。
main.js(主进程)
在这个main.js文件中,我们打开两个窗口进行测试。主窗口将具有Open File Dialog按钮,而辅助窗口将显示所选路径。
收到IPC open-dialog消息后,打开文件对话框。选择路径后,通过IPC将路径发送到辅助窗口。

// Import required electron modules
const electronApp = require('electron').app;
const electronBrowserWindow = require('electron').BrowserWindow;
const electronDialog = require('electron').dialog;
const electronIpcMain = require('electron').ipcMain;

// Import required Node modules
const nodePath = require('path');

// Prevent garbage collection
let primaryWindow;
let secondaryWindow;

function createPrimaryWindow() {
    const primaryWindow = new electronBrowserWindow({
        x: 0,
        y: 0,
        width: 400,
        height: 300,
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            sandbox: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    });

    primaryWindow.loadFile(nodePath.join(__dirname, 'primary-window.html'))
        .then(() => { primaryWindow.show(); });

    return primaryWindow;
}

function createSecondaryWindow() {
    const secondaryWindow = new electronBrowserWindow({
        x: 410,
        y: 0,
        width: 400,
        height: 300,
        parent: primaryWindow, // Child of the primary window
        show: false,
        webPreferences: {
            nodeIntegration: false,
            contextIsolation: true,
            sandbox: true,
            preload: nodePath.join(__dirname, 'preload.js')
        }
    });

    secondaryWindow.loadFile(nodePath.join(__dirname, 'secondary-window.html'))
        .then(() => { secondaryWindow.show(); });

    return secondaryWindow;
}

electronApp.on('ready', () => {
    primaryWindow = createPrimaryWindow();
    secondaryWindow = createSecondaryWindow();
});

electronApp.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        electronApp.quit();
    }
});

electronApp.on('activate', () => {
    if (electronBrowserWindow.getAllWindows().length === 0) {
        createPrimaryWindow();
    }
});

// ---

electronIpcMain.on('open-dialog', () => {
    electronDialog.showOpenDialog(primaryWindow, {properties: ['openFile']})
        .then((result) => {
            // Bail early if user cancels dialog
            if (result.canceled) {
                console.log('User cancelled / closed dialog');
            } else {
                secondaryWindow.webContents.send('send-path', result.filePaths[0]);
                console.log(result.filePaths[0]);
            }
        })
})

preload.js(主进程)
在主进程和呈现进程之间创建IPC消息路径。

// Import the necessary Electron modules
const contextBridge = require('electron').contextBridge;
const ipcRenderer = require('electron').ipcRenderer;

// Exposed protected methods in the render process
contextBridge.exposeInMainWorld(
    // Allowed 'ipcRenderer' methods
    'ipcRenderer', {
        // From main to render
        sendPath: (listener) => {
            ipcRenderer.on('send-path', listener);
        },
        // From render to main
        openDialog: () => {
            ipcRenderer.send('open-dialog');
        }
    }
);

以及如何使用它…

/**
 *
 * Main --> Render
 * ---------------
 * Main:    window.webContents.send('channel', data); // Data is optional.
 * Preload: apiName: (listener) => { ipcRenderer.on('channel', listener); }
 * Render:  window.ipcRenderer.apiName((event, data) => { methodName(data); });
 *
 * Main --> Render (Once)
 * ----------------------
 * Main:    window.webContents.send('channel', data); // Data is optional.
 * Preload: apiName: (listener) => { ipcRenderer.once('channel', listener); }
 * Render:  window.ipcRenderer.apiName((event, data) => { methodName(data); });
 *
 * Render --> Main
 * ---------------
 * Render:  window.ipcRenderer.apiName(data); // Data is optional.
 * Preload: apiName: (data) => { ipcRenderer.send('channel', data) }
 * Main:    electronIpcMain.on('channel', (event, data) => { methodName(data); });
 *
 * Render --> Main (Once)
 * ----------------------
 * Render:  window.ipcRenderer.apiName(data); // Data is optional.
 * Preload: apiName: (data) => { ipcRenderer.send('channel', data); }
 * Main:    electronIpcMain.once('channel', (event, data) => { methodName(data); });
 *
 * Render --> Main (Value) --> Render
 * ----------------------------------
 * Render:  window.ipcRenderer.apiName(data).then((result) => { methodName(result); });
 * Preload: apiName: (data) => { return ipcRenderer.invoke('channel', data); }
 * Main:    electronIpcMain.handle('channel', (event, data) => { return someMethod(data); });
 *
 * Render --> Main (Promise) --> Render
 * ------------------------------------
 * Render:  window.ipcRenderer.apiName(data).then((result) => { methodName(result); });
 * Preload: apiName: (data) => { return ipcRenderer.invoke('channel', data); }
 * Main:    electronIpcMain.handle('channel', async (event, data) => {
 *              return await myPromise(data).then((result) => { return result; })
 *          });
 *
 * Main:    function myPromise(data) { return new Promise((resolve, reject) => { ... }; )};
 *
 */

primary-window.html(渲染过程)
单击button后,向主进程发送IPC消息以打开文件对话框。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Primary Window</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>

    <body>
        <h1>Primary Window</h1>
        <hr>
        <input type="button" id="openDialog" value="Open File Dialog">
    </body>

    <script>
        document.getElementById('openDialog').addEventListener('click', () => {
            window.ipcRenderer.openDialog();
        })
    </script>
</html>

secondary-window.html(渲染过程)
从主进程收到IPC消息后,显示并记录所选文件路径。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Secondary Window</title>
        <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';"/>
    </head>

    <body>
        <h1>Secondary Window</h1>
        <hr>
        <div id="output"></div>
    </body>

    <script>
        window.ipcRenderer.sendPath((event, data) => {
            document.getElementById('output').innerText = data;
            console.log(data);
        })
    </script>
</html>

相关问题