Electron简单示例

Electron简单示例

简单实现electron应用。实现应用菜单栏、任务栏托盘程序及其右键菜单、托盘点击显示/隐藏应用、点击关闭按钮应用隐藏到托盘、注册开机启动。win及Linux下通过electron-packager打包后是一个包含可执行文件及其依赖的文件夹,需要二次制作为对应系统的安装文件,win下使用NSIS可以实现。Linux下使用electron-installer-redhat可以进行rpm制作。Mac下electron-installer-dmg可以将.app制作为dmg安装包。

程序依赖

  • node.js
  • npm
  • electron npm install electron -g
  • electron-packager npm install -g electron-packager打包为一个文件夹其中有应用依赖和一个可执行文件
  • auto-launch npm install --save auto-launch开机启动
  • electron-installer-dmg npm i electron-installer-dmg -g制作dmg安装包
  • electron-installer-redhatnpm install electron-installer-redhat -g(需要rpmbuild通过brew install rpm安装)制作rpm安装包
  • electron-installer-debiannpm install electron-installer-debian -g制作deb安装包

package.json

{
  "name": "helloword",
  "productName":"helloword",
  "version": "1.0.0",
  "description": "这是helloword程序",
  "main": "src/main.js",
  "scripts": {
    "start": "electron .",
    "start_dev": "electron . --debug",
    "package_win": "electron-packager ./ --platform=win32 --arch=x64 --out ./OutApp --electron-version=2.0.0 --icon=./src/image/dao.ico --asar --overwrite",
    "package_win32": "electron-packager ./ --platform=win32 --arch=ia32 --out ./OutApp --electron-version=2.0.0 --icon=./src/image/dao.ico --asar --overwrite",
    "package_osx": "electron-packager ./ --platform=darwin --arch=x64 --out ./OutApp --electron-version=2.0.0 --icon=./src/image/dao_black.icns --asar --overwrite",
    "package_linux": "electron-packager ./ --platform=linux --arch=x64 --out ./OutApp --electron-version=2.0.0 --icon=./src/image/dao_black.ico --asar --overwrite",
    "package_linux32": "electron-packager ./ --platform=linux --arch=ia32 --out ./OutApp --electron-version=2.0.0 --icon=./src/image/dao_black.ico --asar --overwrite",
    "make_dmg": "electron-installer-dmg OutApp/helloword-darwin-x64/helloword.app helloword --out=OutApp/ --overwrite",
    "make_rpm": "electron-installer-redhat --src OutApp/helloword-linux-x64/ --dest OutApp/ --arch x86_64",
    "make_rpm32": "electron-installer-redhat --src OutApp/helloword-linux-ia32/ --dest OutApp/ --arch i386",
    "make_deb": "electron-installer-debian --src OutApp/helloword-linux-x64/ --dest OutApp/ --arch amd64",
    "make_deb32": "electron-installer-debian --src OutApp/helloword-linux-ia32/ --dest OutApp/ --arch i386"
  },
  "author": "张勇波",
  "license": "ISC",
  "dependencies": {
    "auto-launch": "^5.0.5",
    "devtron": "^1.4.0"
  },
  "devDependencies": {
    "electron": "^2.0.0",
    "electron-packager": "^12.1.0",
    "electron-installer-dmg": "^1.0.0",
    "electron-installer-redhat": "^0.5.0",
    "electron-installer-debian": "^0.8.1"
  }
}

main.js

const electron = require('electron');
// const debug = /--debug/.test(process.argv[2]);
const debug = (process.argv.indexOf("--debug") >= 0);
const {
    app,
    BrowserWindow
} = electron;
const path = require('path')
const url = require('url')
//用一个 Tray 来表示一个图标,这个图标处于正在运行的系统的通知区 ,通常被添加到一个 context menu 上.
const Menu = electron.Menu;
const Tray = electron.Tray;
var appTray = null; //托盘程序对象
var appStatus = 'show'; //系统托盘状态标识

// powerSaveBlocker 模块是用来阻止应用系统进入睡眠模式的,因此这允许应用保持系统和屏幕继续工作.
const powerSaveBlocker = require('electron').powerSaveBlocker;
// prevent-app-suspension - 阻止应用挂起. 保持系统活跃,但是允许屏幕不亮. 用例: 下载文件或者播放音频.
// prevent-display-sleep- 阻止应用进入休眠. 保持系统和屏幕活跃,屏幕一直亮. 用例: 播放音频.
var id = powerSaveBlocker.start('prevent-app-suspension');
// powerSaveBlocker.stop(id);

//开机启动
var AutoLaunch = require('auto-launch');
var minecraftAutoLauncher = new AutoLaunch({
    name: 'helloword', //应用名称
    path: process.execPath, //应用绝对路径
    isHidden: false, //是否隐藏启动
    mac: {
        useLaunchAgent: false //是否启用代理启动,默认是AppleScript启动
    }
});

//提示框
const dialog = require('electron').dialog;
// dialog.showMessageBox(win, { type: "info", title: "提示", message: win.isVisible() + '' });

// 保持一个对于 window 对象的全局引用,如果你不这样做,
// 当 JavaScript 对象被垃圾回收, window 会被自动地关闭
let win = null;
//是否退出标示
var force_quit = false;
/**
 * 初始化创建主浏览窗口
 * @return {[type]} [description]
 */
function createWindow() {
    // 创建浏览器窗口。
    let browserOptions = {
        width: 1000,
        height: 600,
        resizable: true,
        // autoHideMenuBar: false, // 自动隐藏菜单栏, 除非按了Alt键
        skipTaskbar: false, // 不显示在任务栏
        show: false,
        transparent: false, //背景透明
        webPreferences: {
            nodeIntegration: false
        } //禁止注入node
        // frame: false, //不显示边框 按钮
    };
    // 创建窗口
    win = new BrowserWindow(browserOptions);
    win.once('ready-to-show', () => {
        win.show();
    });
    win.once('focus', () => win.flashFrame(false));
    // win.show();
    // 然后加载应用的 index.html。
    // win.loadURL(url.format({
    //     pathname: path.join(__dirname, 'index.html'),
    //     protocol: 'file:',
    //     slashes: true
    // }));
    win.loadURL('http://zhangyb.leanote.com');
    // win.loadURL(`file://${__dirname}/index.html`);
    if (debug) {
        win.webContents.openDevTools();
        win.maximize();
        require('devtron').install();
    }
    // 打开开发者工具。
    // win.webContents.openDevTools();

    // 当 window 被关闭,这个事件会被触发。
    win.on('close', (e) => {
        if (!force_quit) {
            e.preventDefault();
            hideTray();
        }
        // dialog.showMessageBox(win, { type: "info", title: "提示", message: (process.platform == 'darwin') + '' });
        //回收BrowserWindow对象
        //mac下关闭为最小化,cms+q或菜单退出为完全退出,
        //win下关闭为隐藏到托盘,并移除任务栏,托盘右键退出为完全退出
        // if (process.platform !== 'darwin') {
        /* if (win.isMinimized()) {
            win = null;
        } else {
            e.preventDefault();
            win.minimize();
            if (process.platform !== 'darwin') {
                appStatus = 'hide';
                appTray.setImage(path.join(__dirname, 'image/dao.png'));
                win.setSkipTaskbar(true);
            }
        } */
        // } else {
        //     dialog.showMessageBox(win, { type: "info", title: "提示", message: win.isVisible() + '' });
        //     win = null;
        // }
    });
    win.on('resize', () => {
        win.reload();
    });
    win.on('closed', function () {
        win = null
    });
}
/**
 * 初始化菜单
 * @return {[type]} [description]
 */
function initMenu() {
    let template = [{
        label: '编辑',
        submenu: [{
            label: '撤销',
            accelerator: 'CmdOrCtrl+Z',
            role: 'undo'
        }, {
            label: '重做',
            accelerator: 'Shift+CmdOrCtrl+Z',
            role: 'redo'
        }, {
            type: 'separator'
        }, {
            label: '剪切',
            accelerator: 'CmdOrCtrl+X',
            role: 'cut'
        }, {
            label: '复制',
            accelerator: 'CmdOrCtrl+C',
            role: 'copy'
        }, {
            label: '粘贴',
            accelerator: 'CmdOrCtrl+V',
            role: 'paste'
        }, {
            label: '全选',
            accelerator: 'CmdOrCtrl+A',
            role: 'selectall'
        }, {
            type: 'separator'
        }, {
            label: '退出',
            accelerator: 'CmdOrCtrl+Q',
            click: function () {
                force_quit = true;
                appTray.destroy();
                app.quit();
                // app.quit();
            }
        }]
    }, {
        label: '查看',
        submenu: [{
            label: '重载',
            accelerator: 'CmdOrCtrl+R',
            click: function (item, focusedWindow) {
                if (focusedWindow) {
                    // 重载之后, 刷新并关闭所有的次要窗体
                    if (focusedWindow.id === 1) {
                        BrowserWindow.getAllWindows().forEach(function (win) {
                            if (win.id > 1) {
                                win.close()
                            }
                        })
                    }
                    focusedWindow.reload()
                }
            }
        }, {
            label: '切换全屏',
            accelerator: (function () {
                if (process.platform === 'darwin') {
                    return 'Ctrl+Command+F'
                } else {
                    return 'F11'
                }
            })(),
            click: function (item, focusedWindow) {
                if (focusedWindow) {
                    focusedWindow.setFullScreen(!focusedWindow.isFullScreen())
                }
            }
        }, {
            label: '切换开发者工具',
            accelerator: (function () {
                if (process.platform === 'darwin') {
                    return 'Alt+Command+I'
                } else {
                    return 'Ctrl+Shift+I'
                }
            })(),
            click: function (item, focusedWindow) {
                if (focusedWindow) {
                    focusedWindow.toggleDevTools()
                }
            }
        }]
    }, {
        label: '窗口',
        role: 'window',
        submenu: [{
            label: '最小化',
            accelerator: 'CmdOrCtrl+M',
            role: 'minimize'
        }, {
            label: '关闭',
            accelerator: 'CmdOrCtrl+W',
            role: 'close'
        }]
    }, {
        label: '帮助',
        role: 'help',
        submenu: [{
            label: '关于',
            click: function () {
                initAbout();
            }
        }, {
            label: '学习更多',
            click: function () {
                electron.shell.openExternal('http://zhangyb.leanote.com/')
            }
        }]
    }];
    //注册菜单
    Menu.setApplicationMenu(Menu.buildFromTemplate(template));
}
/**
 * 创建应用托盘程序及菜单
 * @return {[type]} [description]
 */
function initTrayIcon(tray_reload) {
    if (tray_reload) {
        // dialog.showMessageBox(win, { type: "info", title: "获取是否开机启动", message: tray_reload + '' });
        //系统托盘图标目录
        appTray = new Tray(path.join(__dirname, 'image/dao_black.png'));
        //设置此托盘图标的悬停提示内容
        appTray.setToolTip('helloword托盘程序,点击隐藏/显示应用');
    }
    var label_name = "开机启动";
    minecraftAutoLauncher.isEnabled().then(function (isEnabled) {
        if (isEnabled) {
            label_name = "开机启动(已开启)";
        }
        //系统托盘右键菜单
        var trayMenuTemplate = [{
                label: label_name,
                click: function () {
                    // dialog.showMessageBox(win, { type: "info", title: "开机启动设置", message: process.execPath + '' });
                    minecraftAutoLauncher.isEnabled().then(function (isEnabled) {
                        if (isEnabled) {
                            minecraftAutoLauncher.disable();
                        } else {
                            minecraftAutoLauncher.enable();
                        }
                        initTrayIcon(false);
                    }).catch(function (err) {
                        dialog.showMessageBox(win, {
                            type: "info",
                            title: "开机启动设置",
                            message: err + ''
                        });
                    });
                }
            }, {
                label: '关于',
                click: function () {
                    initAbout();
                }
            },
            {
                label: '退出',
                click: function () {
                    force_quit = true;
                    appTray.destroy();
                    // app.quit();
                    app.quit(); //因为程序设定关闭为最小化,所以调用两次关闭,防止最大化时一次不能关闭的情况
                }
            }
        ];
        //图标的上下文菜单
        const contextMenu = Menu.buildFromTemplate(trayMenuTemplate);
        //设置此图标的上下文菜单
        appTray.setContextMenu(contextMenu);
    }).catch(function (err) {
        // handle error
    });
    // dialog.showMessageBox(win, { type: "info", title: "获取是否开机启动", message: label_name + '123' });

    // if (process.platform === 'darwin') {
    //     //如果是苹果系统 托盘菜单的图标
    //     appTray = new Tray(path.join(__dirname, 'image/dao.png'));
    // } else {
    //     appTray = new Tray(path.join(__dirname, 'image/dao.png'));
    // }


    if (process.platform !== 'darwin') {
        //单击托盘图标显示/隐藏应用
        appTray.on("click", function () {
            if (win === null) {
                createWindow()
            }
            //主窗口显示隐藏切换
            if (win.isVisible() && appStatus === 'show') {
                hideTray();
            } else {
                appStatus = 'show';
                appTray.setImage(path.join(__dirname, 'image/dao_black.png'))
                win.show();
                win.setSkipTaskbar(false);
            }
        });
    }
    //系统托盘图标闪烁
    // var count = 0,
    // timer = null;
    // timer = setInterval(function() {
    //     count++;
    //     if (count % 2 == 0) {
    //         appTray.setImage(path.join(trayIcon, 'dao_black.png'))
    //     } else {
    //         appTray.setImage(path.join(trayIcon, 'dao.png'))
    //     }
    // }, 600);
}

/**
 * @description 隐藏程序界面并修改托盘图标
 * @author 张勇波
 */
function hideTray() {
    win.hide();
    if (process.platform !== 'darwin') {
        appStatus = 'hide';
        appTray.setImage(path.join(__dirname, 'image/dao.png'));
        win.setSkipTaskbar(true);
    }
}

/**
 * 关于窗口初始化
 * @return {[type]} [description]
 */
function initAbout() {
    var win_gy = new BrowserWindow({
        width: 400,
        height: 300,
        resizable: false,
        parent: win,
        modal: true,
        show: false,
        // transparent: true,//背景透明
        frame: false //不显示边框 按钮
    });
    win_gy.loadURL('http://blog.leanote.com/single/zhangyb/关于');
    // win_gy.loadURL(`file://${__dirname}/about.html`);
    win_gy.once('ready-to-show', () => {
        win_gy.show();
    });
    win_gy.on('blur', () => {
        win_gy.close();
    });
    win_gy.on('closed', () => {
        win_gy = null
    });
}
var shouldQuit = app.makeSingleInstance(function (commandLine, workingDirectory) {
    // 当另一个实例运行的时候,这里将会被调用,我们需要激活应用的窗口
    if (win) {
        if (win.isMinimized()) win.restore();
        win.focus();
    }
    return true;
});
// 这个实例是多余的实例,需要退出
if (shouldQuit) {
    app.quit();
    return;
}
// 当全部窗口关闭时退出。
app.on('window-all-closed', () => {
    // 在 macOS 上,除非用户用 Cmd + Q 确定地退出,
    // 否则绝大部分应用及其菜单栏会保持激活。
    if (process.platform !== 'darwin') {
        // app.quit();
        hideTray();
    }
});
app.on('before-quit', function (e) {
    if (!force_quit) {
        e.preventDefault();
        hideTray();
        /* win.hide();
        if (process.platform !== 'darwin') {
            appStatus = 'hide';
            appTray.setImage(path.join(__dirname, 'image/dao.png'));
            win.setSkipTaskbar(true);
        } */
    }
})
app.on('will-quit', function () {

    win = null;
})
app.on('activate', () => {
    // 在macOS上,当单击dock图标并且没有其他窗口打开时,
    // 通常在应用程序中重新创建一个窗口。
    win.show();
    if (win === null) {
        createWindow()
    }
});
// Electron 会在初始化后并准备
// 创建浏览器窗口时,调用这个函数。
// 部分 API 在 ready 事件触发后才能使用。
app.on('ready', () => {
    createWindow(); //主程序
    initMenu(); //主程序菜单
    initTrayIcon(true); //托盘程序
});

问题

编写完package.json后若启动或编译项目有cannot find module 之类的错误,可以尝试删除项目下的node_modules文件夹和package-lock.json文件,然后在项目根目录下执行npm install

NSIS2.46(制作windows下安装包工具)


 上一篇
Electron引入js的方法 Electron引入js的方法
Electron引入js的方法<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> <
2019-08-19
下一篇 
Excel表格转html Excel表格转html
Excel表格转htmlimport org.apache.poi.hssf.usermodel.*; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.
2019-08-19
  目录