指定路径将文件写入剪贴版的C++dll工程,并附Electron+Vue使用例

3 篇文章 0 订阅
1 篇文章 0 订阅

一、背景

在使用electron开发桌面应用,尤其是类似微信的即时通讯IM应用,会考虑各种情况的文件操作,比如弹窗选择、拖拽、或者复制粘贴的方式发送文件消息,这些操作都是基于文件本身的,所以都好处理。但是如果对文件消息进行复制,就会存在两种可能性:

  1. 一是本文件消息对应的服务器文件存在时,只需要发送一个同样的文件消息(文件直接指向原消息的服务器文件)即可;
  2. 再一个就是原文件消息对应的服务器文件不存在时,又有两种情况需要考虑:
    2.1 如果本地文件也不存在时,当然复制、转发之类的也就不能再显示了;
    2.2 如果本地文件存在时(如下图所示)
    在这里插入图片描述
    在复制时就需要用消息体中的文件路径,将本地文件写入到剪贴板中,也就是本文所讲内容的使用场景;

二、使用

  1. clone工程【https://gitee.com/lykiao/copy-file-to-clipboard.git】,使用vs2019编译工程生成【CopyFileToClipboard.dll】
  2. electron工程的src文件夹(background.js的同级目录)中,创建【CopyFileToClipboard.js】,
    并引入本工程编译生成的dll文件【CopyFileToClipboard.dll】,也可使用【dll_x64_release】文件夹中提供的现成dll文件
    【CopyFileToClipboard.js】的全代码如下:
// 不能用import,会报错,必须放在最外层引入
    const { app } = require('electron');
    try{
      const ffi = require('ffi-napi');
      var path = require('path');
    
      // 重启系统im自动启动时路径有变,需要重置绝对路径,否则报Win32 error 126错误(此处貌似不需要)
      // var oldPath = process.env.PATH;
      // var dllPath = 'C:\\Windows\\SysWOW64\\';
      // process.env['PATH'] = `${process.env.PATH};${dllPath}`;
      const kernel32_ffi = ffi.Library('kernel32', {
          SetDllDirectoryA: ['bool', ['string']]
        });
      // process.env['PATH'] = oldPath;
      // 重启系统im自动启动时路径有变,需要指定绝对路径,否则报Win32 error 126错误
      var resourcesPath = getResourcesPath();
      kernel32_ffi.SetDllDirectoryA(resourcesPath); // 必须指定绝对路径
      // c++的dll中不能带namespace和class,否则找不到function
      const CopyFileToClipboard = ffi.Library('CopyFileToClipboard.dll', {
          'RunCopyFile': // 声明这个dll中的一个函数
            [
              'int', ['string'],  // 前为出力参数,后为入力参数
            ],
        });
    
      const RunCopyFile = function(fullPath){
          console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++文件copy开始: " + fullPath);
          var result = CopyFileToClipboard.RunCopyFile(fullPath);
          console.log("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++文件copy结束: " + result);
      };
    
      module.exports = {CopyFileToClipboard, RunCopyFile};
    }catch(e){
      // 如果background.js中一开始就引入此js,taskbar中点击翼丰信,background.js中second-instance激活主窗体后会报dll错,已在使用时引入,以防万一,在此catch住
      console.log("=======error: ffi-napi 引入 CopyFileToClipboard.dll 出错!!!")
      console.error(e);
    }
    
    // 此方法必须放在外层,而且不能写成const getResourcesPath = function(){}的形式,否则报错
    function getResourcesPath(){
      if (process.env.WEBPACK_DEV_SERVER_URL){
        const devUrl =  'resources/dll/';
        return devUrl;
      }else{
          var appPath = path.dirname(app.getPath('exe'));
          const eveUrl = appPath + '\\resources\\dll\\';
          console.log("************CopyFileToClipboard prod dllPath: " + eveUrl);
          return eveUrl;
      }
    }

3、在【background.js】中引入以上【CopyFileToClipboard.js】

	// 引入:
    const { RunCopyFile } = require("./CopyFileToClipboard");
    
    // 使用:
    // 执行本地文件copy操作
    ipcMain.on('CopyFileToClipboard', (event, args) => {
        console.log("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++执行文件copy: " + args.fullPath);
        // 之前以下两种情况报错是因为重启电脑im自动启动导致环境变量指定的路径有变,已解决:
        // 1、电脑重启后立即启动app,会报ffi-napi找不到dll的win32 error 126错误,导致dll加载失败
        // 2、taskbar任务栏右键点选翼丰信后,在触发second-instance前也会报上面的错
        // require("./CopyFileToClipboard").RunCopyFile(args.fullPath);
        RunCopyFile(args.fullPath);
    });

4、前端vue文件可直接发送事件,触发以上后台方法执行

// 发送事件:
    ipcRenderer.send('CopyFileToClipboard', {fullPath: message.messageContent.localPath});
    
    // 执行粘贴:
    // 这样,在ctrl+v调起的handlePaste(e)方法中就可以从剪贴板中获取到文件了
    var clipboardFiles = e.clipboardData.files;

以上,也请多注意代码中的注释,都是个人爬坑时留下的痕迹 TT

  • 23
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值