实战electron项目相关知识点汇总

这篇博客详细介绍了如何在Electron应用中实现浏览器视图的缓存清理、窗口尺寸及位置的获取与设置,以及系统右键菜单的自定义。同时,文章讲解了如何监听和管理下载服务,包括下载状态跟踪、文件保存路径等。此外,还涉及进程管理、文件读写、文件选择对话框的使用,以及如何在不同操作系统下打开文件。最后,讨论了Electron应用中的托盘图标及其事件处理,展示了创建托盘菜单的方法。
摘要由CSDN通过智能技术生成

清缓存当前打开的BrowserView页面后,重新加载

view.browserView.webContents.session.clearCache().then(()=>{
    view.browserView.webContents.reload()
})

获取窗口的宽、高、位置

const { width, height, x, y } = this.newsWin.getBounds()

重新设置窗口的宽、高、位置

this.newsWin.setPosition(x, y, true)
this.newsWin.setSize(width, height)

获取当前窗口的宽、高、位置

const { width, height, x, y } = win.getContentBounds()

设置当前的窗口的宽、高、位置

const newBounds = {
    x: 0,
    y: 0,
    width,
    height
}
view.browserView.setBounds(newBounds)

系统单机右键菜单

import { Menu } from 'electron'
Menu.buildFromTemplate([
    {
        label: '分屏显示',
        click: () => {
            
        }
    },
    {
        label: '本地浏览',
        click: () => {
            
        }
    },
    {
        label: '关闭窗口',
        click: () => {
            
        }
    }
])

监听browserView窗口的下载服务

import { session } from 'electron'

getDownloadItem(item, id) {
    return {
        fileName: basename(item.getFilename()),
        receivedBytes: item.getReceivedBytes(),
        totalBytes: item.getTotalBytes(),
        savePath: item.getSavePath(),
        id
    }
}

const view = session.fromPartition("persist:view")
view.on("will-download", (e, item, webContents) => {
    const id = uuid.v4()
    const downloadItem = this.getDownloadItem(item, id)

    item.on("updated", (event, state) => {

        if (state === "interrupted") {
            console.log("download is interrupted but can be resumed")
        } else if (state === "progressing") {
            const data = this.getDownloadItem(item, id)
            console.log("progressing", data)
            if (item.isPaused()) {
                console.log("download is paused")
            }
            if (!!data.savePath) {
                
            }

        }
    })

    item.once("done", (event, state) => {
        if (state === "completed") {
            console.log("download completed")
            const data = this.getDownloadItem(item, id)
        } else {
            console.log(`download failed: ${state}`)
        }
    })
})

session.defaultSession.on("will-download", (e, item, webContents) => {
    const id = uuid.v4()
    const downloadItem = this.getDownloadItem(item, id)
    console.log("will-download")
    item.on("updated", (event, state) => {
        if (state === "interrupted") {
            console.log("download is interrupted but can be resumed")
        } else if (state === "processing") {
            if (item.isPaused()) {
                console.log("download is paused")

            }
        }
    })

    item.once("done", (event, state) => {
        if (state === "completed") {
            console.log("download completed")
            const data = this.getDownloadItem(item, id)
        } else {
            console.log(`download failed: ${state}`)
        }
    })
})

electron下载文件

import request from 'request'
import { basename, join, resolve } from "path"
import  fs  from "fs"
import adm_zip from 'adm-zip'

const url = '文件下载的路径'
const toZipPath = join('E:/downloadapp/', 'fileName.zip') // fileName.zip是需要下载的文件名称.zip【自定义,必须带有后缀.zip或者.doc,否则下载文件不可用】
const stream = fs.createWriteStream(toZipPath)
request(url).pipe(stream).on('close', (err) => {
    console.log('下载完毕')
    // 压缩包解压
    const unzip = new adm_zip(toZipPath);
    unzip.extractAllTo( join('E:/downloadapp/', 'fileName') ,true)
    exec('chmod +x '+ this.downloadDirPath +'/* -R')
})

获取系统进程

// child_process无需安装,系统自带

import { exec } from 'child_process'

let cmd = process.platform === 'win32' ? 'cmd.exe /c wmic process list full' : 'ps aux'; // 'tasklist'
exec( cmd, (err, stdout, stderr) => {
    if(err){
        return console.error('err')
    }
    let _list = []
    // stdout = `USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
    // `
    if(process.platform == 'win32'){
        stdout.split('CommandLine').map(d=>{
            const A = ('CommandLine'+d).split('\n').filter(m=>m.trim()!='');
            const _js = {}
            if(A[0] !== "CommandLine"){
                A.map(a => {
                    const b = a.split('=');
                    if(b[1]){
                        _js[b[0]] = b[1].replace(/[\r\n]/g, "")
                    }
                })
                _list.push(_js)
            }
        })
        
    }else{
        stdout.split('\n').map(line=>{
            let _temp = {}
            const _obj = line.trim().split(/\s+/)
            _temp.user = _obj[0]
            _temp.ProcessId = _obj[1]
            _temp.cpu = _obj[2]
            _temp.WorkingSetSize = _obj[3]
            _temp.vsz = _obj[4]
            _temp.rss = _obj[5]
            _temp.tty = _obj[6]
            _temp.stat = _obj[7]
            _temp.start = _obj[8]
            _temp.time = _obj[9]
            _temp.CommandLine = _obj[10]
            if(_obj[11]){
                _obj.map((d,index) => {
                    if(index > 10){
                        _temp.CommandLine = _temp.CommandLine + ' '+d
                    }
                })
            }
            
        })
    }

    console.log(_list)
    
} )

终止进程, process无需引入,也无需安装,系统自带

process.kill([ProcessId进程ID])

electron文件选择弹出框

dialog.showOpenDialog( {
    title: '选择文件',
    properties: ['openFile','openDirectory', 'openFile'],
    filters: {name:'文件夹',extensions: ['file']}
}).then(result=>{
    if(result.filePaths && result.filePaths[0]){
        console.log(result.filePaths[0])
    }
})

nodeJS判断文件是否存在

fs.existsSync("public/images/process_icon.png")

nodeJS读取文件,把image图片转成base64码

let imagePath = getPath("public/images/process_icon.png")
if(fs.existsSync(imagePath)){
    let buf = fs.readFileSync(imagePath)
    processIcon = `data:image/png;base64,${buf.toString("base64")}`
}

electron打开一个工具文件,比如,在window下打开一个绿色版本的exe文件;在linux下打开一个可执行文件

if(process.platform === 'win32'){
    shell.openPath('E://downloadapp/netbeas88_441/netbeas8/bin/netbeans.exe') // exe文件路径
}else{
    // 注意:在linux下打开一个可执行文件,首先要给他赋权
    exec('chmod +x /home/download/* -R')
    exec('/home/download/FeiQ/Fqimag') // exec([可执行程序文件的路径,Fqimag就是那个可执行文件])
}

nodeJs读取文件内容

import jsonfile from "jsonfile"
const { app } = require("electron")
const {resolve, join} = require("path")

const getPath = (str) => {
    if (process.env.NODE_ENV == "development"){
        return resolve(str)
    }
    return join(app.getAppPath("exe"), str)
}
this.configPath = getPath("./config/config.json")
this.config = jsonfile.readFileSync(this.configPath)

nodeJs写入文件

// 把{name:'sssss'}对象写入config.json文件中
// spaces格式化的意思
jsonfile.writeFileSync(this.configPath, {name:'sssss'}, { spaces:4 })

electron打开文件位置/打开文件

shell.openPath(toDownloadIconPath)
shell.showItemInFolder(toDownloadIconPath)
shell.openExternal(toDownloadIconPath)

electron托盘

import { Tray, app } from 'electron'
this.iconPath = getPath('./public/ichat-new.png')
this.tray = new Tray(this.iconPath)
this.tray.on('click', () => {
    // 点击托盘显示主窗口
})

给托盘增加单机右键的事情

const menu = Menu.buildFromTemplate([{
    click() {
       // 
    },
    label: '显示窗口',
    type: 'normal'
}, {
    click() {
        // 
    },
    label: '切换用户',
    type: 'normal'
}, {
    click() {
       //
        app.quit()
    },
    label: '退出',
    type: 'normal'
}])
this.tray.setContextMenu(menu)

监听鼠标移动到托盘的事情

this.tray.on('mouse-move', () => {
    _this.isLeave = false
    _this.checkTrayLeave()
})

监听鼠标离开托盘
因为没有鼠标离开托盘的事情,所以,在鼠标移动托盘时,做一个定时器,随时监听鼠标的位置是否在托盘的位置上
鼠标的位置没有在托盘的位置范围内,表示鼠标已经离开托盘

checkTrayLeave() {
    let _this = this
    _leaveTrayTimer && clearInterval(_leaveTrayTimer)
    _leaveTrayTimer = setInterval(() => {
        const { x, y, width, height } = _this.newsWin.getBounds()
        const point = screen.getCursorScreenPoint()
        const x1 = point.x
        const y1 = point.y
        if (!(y1 > y && y1 < y + height + 50 &&
            x1 > x && x1 < x + width)
        ) {
            clearInterval(_leaveTrayTimer)
            _this.isLeave = true
            _this.newsWin.hide()
        }
    }, 100)
}

对于 Electron 项目的开发实战,有很多方面需要考虑,包括项目的结构、界面设计、数据处理等。以下是一些常见的实践建议: 1. 项目结构:创建一个清晰的项目结构,将主进程和渲染进程的代码分开放置,并使用合适的模块化方式组织代码。可以使用一些现有的脚手架工具来快速生成项目结构。 2. 界面设计:使用现代化的前端技术(如 HTML、CSS 和 JavaScript)来开发界面。可以考虑使用流行的前端框架(如 React、Vue.js)来简化界面开发,并且可以借助 Electron 提供的 IPC(进程间通信)机制在主进程和渲染进程之间进行通信。 3. 数据处理:根据项目需求选择合适的数据处理方案。如果需要持久化存储数据,可以使用 Electron 提供的 API(如 fs 模块)进行文件操作,或者考虑使用数据库(如 SQLite、MongoDB)进行数据管理。 4. 调试与测试:在开发过程中,可以使用 Electron 提供的调试工具来帮助定位问题。另外,编写单元测试和集成测试也是保证代码质量的重要手段。 5. 打包与发布:完成开发后,需要将项目打包为可执行文件并进行发布。可以使用 Electron 提供的打包工具(如 electron-builder)将项目打包成适用于不同平台的安装包。 总之,开发 Electron 项目需要掌握前端技术、Electron相关 API 使用方法,并且在项目开发过程中注重代码质量和用户体验。希望这些实践建议能对你有所帮助!如果还有其他问题,欢迎继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hongc93

感谢鼓励 继续航行

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值