我和electron有个误会(二)

311 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天


背景介绍

公司接到需求,需要使用开发一个桌面程序用于客户自助机使用,因为没有人会搞桌面端开发,身为啥都搞的前端程序员,身披战袍出战


那么书接上回,刚刚完成个性化安装需求,准备向产品炫耀,产品突然黑着脸和我说,客户又来了需求,这次需要我们的桌面程序去调用客户的应用,客户的应用是.net写,纳尼,跨语言调用,好家伙。经过仔细调研,过来没什么事可以难道天下第一javascrip--[狗头保命]

image.png

image.png

在github上找到了一个库,利用node调用.net,完美可以解决需求,上回说到服务端的框架使用express,那么我就写个接口就完事了,开搞开搞

   npm i edge-js
    const helloJueJin = () edge.func(`
        async () => {
            return 'hello JueJin'
        }
    `)
    express.get('/diaoyongdotnet', (req, res) => {
        helloJueJin(null, (err, result) => {
            if (err) {
                res.send(result)
            }
            res.send(result)
        })
    })

前端调用,返回hello JueJin, 完美完美,然后我就找负责写.net的同事写了个dll给我调用,当我觉得一切都会顺利的时候,问题来了🐕


坑!我走过的坑希望你们都走一遍,大家手拉手

当我使用以下代码调用同事写的dll时,问题来了,当然不是我的问题

   express.get('/diaoyongdotnet', (req, res) => {
       // 前端参数
       const body = req.body
       // 调用路径文件DLL
       const driver = edge.func({
           // DLL路径
          assemblyFile: body.path,
          // DLL的Class,写.NET的知道,让他告诉你
          typeName: 'AutoShell.frmMemo',
          // DLL我们需要调用的方法
          methodName: 'Print_Patient_Reports'
        })
        // 运行上面edge的方法  第一个参数是传入.net的参数
        driver(Number(body.code), function(err,result) {
          if (err) {
            res.send(restful.error(err, 'dll读取出错'))
          } else {
            res.send(result) 
          }
        })
    })

结果报错,纳尼

d3e8c98516cbd7d90e20792b67069c2.jpg

看起来是.net那边的报错,经过日夜不断的调试,终于找到原因了,原来是文档没看全,.net使用的框架必须是.net 4.5的框架,不然会调用出错

image.png

等同事重新生成dll,再次调用终于成功了🤭

当然因为我们是用electron框架的,所以需要把包换成electron-edge-js这个包,对应electron的版本也不能太高,我这边用的是17.x.x的版本,为什么最后才写这么关键的信息,就是为了让你们看完🐕


在教一招,直接调用exe程序

既然dll都能调用了,顺便把调用exe也说了,使用nodechild-process库,可以调用系统应用

   npm i child-process binary iconv-lite
     const child = require('child_process')
     // 报错信息转码 不然会乱码
     const binaryEncoding = require('binary')
     const iconv = require('iconv-lite')
     // 转码成GBK
     const encoding = 'cp936'
    
     child.exec(`xxx调用地址`, { encoding: binaryEncoding }, (err, stdout, stderr) => {
        if (err) {
          const errMsg = {
              err,
              msg: iconv.decode(new Buffer(stderr, binaryEncoding), encoding) || '调用失败'
          }
          res.send(errMsg)
        }else {
          res.send('ok')
        }
      })
   

经过一天的调试,终于完成了这个新奇需求的开发,当我又准备去找产品炫耀的时候,产品又黑着脸,"我们现在更新每次要客服重新下载我们的安装包,客户觉得麻烦,我希望可以做热更新",😱好家伙,来源不断的需求。。。明天给我等着


关于作者

一个工作三年,摆烂躺平的前端攻城狮~~~🦁

往期链接

我和electron有个误会