electron 里 node-pty 报错解决

electron 不知道为什么用不了 node-pty

目前找到的解决方法是用 child_process.fork() 创建子进程,在子进程里运行 node-pty

由于electron 引入node-pty报错,且 asar 不能打包 node-pty ,所以动态载入 import(“node-pty”)

在这里插入图片描述

核心方法

import { Pty客户端_Fork }   from "...../服务端_pty终端.mjs" 

let 子进程脚本路径 = "...../服务端_pty终端.mjs" 

const pty终端 = new Pty客户端_Fork(子进程脚本路径)
pty终端.spawn( "bash", [], {                           //打开 bash 终端   
     name:'xterm-256color' ,          //配色名必须是 xterm-256color //echo $TERM  xterm-256color  配色
     env:process.env, 
     cwd:窗口启动信令.工作目录 || os.homedir() , 
     指令:窗口启动信令.指令 || "" 
 })  
    
 pty终端.onData(data=>{       })
        

服务端_pty终端.mjs ------------- 脚本 如下

/*
  ------  子进程脚本  -------------------------------
  此脚本作为子进程运行(被 fork 调用)  不能被 asar 压缩 !!!

  此脚本和它的父进程 IPC通信   process.send   process.on
*/
import child_process from "child_process" 

export { Pty客户端_Fork }
 
// pty 用原生 send 发送信令 并未包装
class Pty客户端_Fork{              // 为什么封装 pty   , 因为electron 不支持 这类模块   Error:Loading non-context-aware native module in renderer:        
    constructor(pty服务进程脚本路径){
        this.fork进程 =  child_process.fork( pty服务进程脚本路径 , {execArgv:process.execArgv }) 
        this.pid = this.fork进程.pid
        this.onPty退出((err)=>{console.log(err)})   //监控状态
    }
    onPty退出(回调函数){
        this.fork进程.addListener("error",      err=>{ 回调函数({类型:"pty终端  fork子进程error",数据:err})           })
        this.fork进程.addListener("close",      ()=>{  回调函数({类型:"pty终端  fork子进程close",数据:this.js脚本路径})  })
        this.fork进程.addListener("exit",       ()=>{  回调函数({类型:"pty终端  fork子进程exit" })  })
        this.fork进程.addListener("disconnect", ()=>{  回调函数({类型:"pty终端  fork子进程disconnect" })  })
        this.onExit( (err)=>回调函数({类型:"pty终端主动退出",数据:err})    )
    }
    kill(){                      this.fork进程.send({类型:"kill"})  ; this.fork进程.kill()   }
    write(字符串){                this.fork进程.send({类型:"write", 数据: 字符串})   }
    spawn(file, args, options){  this.fork进程.send({类型:"spawn", 数据:{file: file, args:args, options:options }} )   }
    resize(columns,rows){        this.fork进程.send({类型:"resize", 数据:{columns: columns, rows:rows }} )   }
    onData(回调函数){             this.fork进程.addListener("message",信令=>{   if(信令.类型==="onData") 回调函数(信令.数据)    })  }
    onExit(回调函数){             this.fork进程.addListener("message",信令=>{   if(信令.类型==="onExit") 回调函数(信令.数据)   })  }
}


//服务端
class pty服务端{
    constructor(){
        this.终端  
    }
    async spawn(file, args , options){  
        try{ // 主进程里引入 node-pty 报错  只能动态引入
            const pty = await import("node-pty") 
            this.终端 = pty.spawn(file, args  , options )  
            this.__proto__.__proto__= this.终端              //继承了所有方法  这里的 spawn 优先执行
        }catch(err){
            process.send({类型:"onExit", 数据:{来源:"pty.spawn() 启动失败", err:err}}) 
        }
    }
}


//================ 如果是子进程 运行服务端 ================== 
if(process?.send || process?.parentPort ){                                                   //child_process  /   electron UtilityProcess  
    const pty终端 = new pty服务端()        // 可以看作只修改了spawn方法原 pty 
    const 同步信令处理表={
        "spawn":async 数据=>{
            //创建进程
            await pty终端.spawn(数据.file, 数据.args  , 数据.options )                         //打开 bash 终端   配色名必须是 xterm-256color //echo $TERM  xterm-256color  配色
            pty终端.onData( data=>{  process.send({类型:"onData", 数据:data }) })       //🌷🌷🌷
     
            pty终端.onExit( err=>{   process.send({类型:"onExit", 数据:err})   })
            //运行传入指令
            if(数据.options.指令) setTimeout(()=>{ pty终端.write(`${数据.options.指令}\n`) } ,50) 
        },
        "write":数据=>{ pty终端.write(数据) },
        "kill":数据=>{  pty终端.kill() ; process.exit() },
        "resize":数据=>{  pty终端.resize(数据.columns,数据.rows) },
    }
    
    //child_process
    process?.on?.("message", 信令=>{  同步信令处理表[信令.类型]?.(信令.数据)  })  //调用
    process?.send?.("启动完成")  // 向父进程 握手
}


 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值