猿问

Electron - 在打开保存对话框之前写入文件

我正在使用电子开发一个应用程序。完成一些加密操作后,我需要向用户显示一个对话框来保存文件。我想给文件的文件名是一个随机哈希,但我也没有成功。我正在尝试使用此代码,但文件不会被保存。我该如何解决这个问题?


const downloadPath = app.getPath('downloads')


ipcMain.on('encryptFiles', (event, data) => {

  let output = [];

  const password = data.password;

  data.files.forEach( (file) => {

    const buffer = fs.readFileSync(file.path);

    const dataURI = dauria.getBase64DataURI(buffer, file.type);

    const encrypted = CryptoJS.AES.encrypt(dataURI, password).toString();

    output.push(encrypted);

  })

  const filename = hash.createHash('md5').toString('hex');

  console.log(filename)

  const response = output.join(' :: ');

  dialog.showSaveDialog({title: 'Save encrypted file', defaultPath: downloadPath }, () => {

    fs.writeFile(`${filename}.mfs`, response, (err) => console.log(err) )  

  })

})


慕桂英546537
浏览 99回答 1
1回答

元芳怎么了

您遇到的问题是由 Electron 的 UI 函数的异步性质引起的:它们不采用回调函数,而是返回承诺。因此,您不必传入回调函数,而是处理 Promise 的解析。请注意,这仅适用于 Electron >= 版本 6。但是,如果您运行旧版本的 Electron,您的代码将是正确的 - 但您应该真正更新到较新的版本(Electron v6 已发布一年多前) 。像下面这样调整您的代码可以作为解决您的问题的起点。但是,由于您没有说明如何生成哈希(来自哪里hash.createHash?;您是否忘记声明/导入hash?;您是否忘记传递任何消息字符串?;您是否用作NodeJS模块hash的别名?) crypto,(此时)不可能调试为什么你没有得到任何输出console.log (filename)(我假设你的意思是“在代码中,不会创建随机文件名”)。一旦您提供有关此问题的更多详细信息,我很乐意相应地更新此答案。至于默认文件名:根据Electron 文档,您可以传递一个文件路径来dialog.showSaveDialog ()为用户提供默认文件名。您正在使用的文件类型扩展名实际上也应该与文件扩展名一起传递到保存对话框中。此外,将此文件扩展名作为过滤器传递到对话框中将阻止用户选择任何其他文件类型,这最终也是您当前通过将其附加到文件名来执行的操作。另外,您可以利用 CryptoJS 来生成文件名:给定一些任意字符串(实际上可能是随机字节),您可以这样做:filename = CryptoJS.MD5 ('some text here') + '.mfs';但是,请记住明智地选择输入字符串。MD5 已被破解,因此不应再用于存储机密 — 使用任何对您存储的文件加密至关重要的已知信息(例如 )本质上data.password是不安全的。考虑到所有这些问题,最终可能会得到以下代码:const downloadPath = app.getPath('downloads'),      path = require('path');ipcMain.on('encryptFiles', (event, data) => {  let output = [];  const password = data.password;  data.files.forEach((file) => {    const buffer = fs.readFileSync(file.path);    const dataURI = dauria.getBase64DataURI(buffer, file.type);    const encrypted = CryptoJS.AES.encrypt(dataURI, password).toString();    output.push(encrypted);  })  // not working:  // const filename = hash.createHash('md5').toString('hex') + '.mfs';  // alternative requiring more research on your end  const filename = CryptoJS.MD5('replace me with some random bytes') + '.mfs';  console.log(filename);  const response = output.join(' :: ');  dialog.showSaveDialog(    {      title: 'Save encrypted file',      defaultPath: path.format ({ dir: downloadPath, base: filename }), // construct a proper path      filters: [{ name: 'Encrypted File (*.mfs)', extensions: ['mfs'] }] // filter the possible files    }  ).then ((result) => {    if (result.canceled) return; // discard the result altogether; user has clicked "cancel"    else {      var filePath = result.filePath;      if (!filePath.endsWith('.mfs')) {        // This is an additional safety check which should not actually trigger.        // However, generally appending a file extension to a filename is not a        // good idea, as they would be (possibly) doubled without this check.        filePath += '.mfs';      }      fs.writeFile(filePath, response, (err) => console.log(err) )      }  }).catch ((err) => {    console.log (err);  });})
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答