Electron 读取本地配置 增加缩放功能(ctrl+scroll)

最近,一个之前做的electron桌面应用,需要增加两个功能;第一是读取本地的配置文件,然后记载配置文件中的ip地址;第二就是增加缩放功能;

第一,配置本地文件

首先需要在vue工程根目录中,新建一个config.json文件;如下图

config.json内容如下:

{
  "ip": "1.11.21.219",
  "port": 30002,
}

然后在vue.config.js中需要排除这个文件,如下:

    // 添加electron - app -icon
    pluginOptions: {
        electronBuilder: {
            builderOptions: {
                productName: 'xxxx', //项目名,也是生成的安装文件名
                //copyright: "Copyright © 2019",//版权信息
                win: {
                    icon: './public/favicon.ico',
                    // 以管理员权限运行
                    requestedExecutionLevel: 'requireAdministrator',
                    target: [{
                        target: "nsis", //利用nsis制作安装程序
                        arch: [
                            "x64", //64位
                        ]
                    }],
                    
                },
                nsis: {
                    oneClick: false, // 是否一键安装
                    allowElevation: true, // 允许请求提升。 如果为false,则用户必须使用提升的权限重新启动安装程序。
                    allowToChangeInstallationDirectory: true, // 允许修改安装目录
                    installerIcon: "./public/favicon.ico", // 安装图标
                    uninstallerIcon: "./public/favicon.ico", //卸载图标
                    installerHeaderIcon: "./public/favicon.ico", // 安装时头部图标
                    createDesktopShortcut: true, // 创建桌面图标
                    createStartMenuShortcut: true, // 创建开始菜单图标
                    shortcutName: "MIES", // 图标名称
                },
                directories: {
                    output: "./MIES_SETUP" //输出文件路径
                },



                /**** 注意这里 配置config.json ****/





                extraResources: [
                    { "from": "./config.json", "to": "../" }
                ],
            },
            nodeIntegration: true,
            preload: 'src/preload.js'
        }
    },
    // 

然后,安装桌面应用之后,会在安装目录出现这个配置好的config.json.

第二,读取本地配置文件,创建window

在backgroundjs中,使用nodejs的fs模块读取根目录下的config.json文件,动态获取配置的ip和端口,然后创建window。

代码如下:

............







// Create the browser window.
let win = null;

async function createWindow() {
  // 读取信息
  var exePath = path.dirname(app.getPath("exe")).replace(/\\/g, "/");
  // console.log(exePath);
  var configPath = `${exePath}/config.json`;

  var sockets = [];


   // ********************   这里是主要功能   ************************* //
   // 读取本地文件 获取配置信息

  fs.readFile(configPath, "utf-8", async (err, data) => {
    if (data) {
      const cp = require("child_process");
      let res = JSON.parse(data);
      const PAGE_URL = `https://${res.ip}:${res.port}`;
      // 创建窗口
      win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          // Use pluginOptions.nodeIntegration, leave this alone
          // See nklayman.github.io/vue-cli-plugin-electron-builder/guide/security.html#node-integration for more info
          // process.env.ELECTRON_NODE_INTEGRATION
          nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
          contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION,
          preload: path.join(__dirname, "/preload.js"),
          webSecurity: false,
          allowRunningInsecureContent: false,
          //zoomFactor: 0.6,
        },
        icon: path.join(__dirname, "./favicon.ico"),
      });

      if (process.env.WEBPACK_DEV_SERVER_URL) {
        // Load the url of the dev server if in development mode
        //await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL);
        console.log("PAGE_URL ----- ", PAGE_URL);
        await win.loadURL(PAGE_URL);
        if (!process.env.IS_TEST) win.webContents.openDevTools();
      } else {
        createProtocol("app");
        // Load the index.html when not in development
        // win.loadURL('app://./index.html');
        //win.loadURL(path.join(__dirname, "./index.html"));
        // https://www.electronjs.org
        console.log("PAGE_URL ----- ", PAGE_URL);
        win.loadURL(PAGE_URL);
      }

      //进入软件即开启全屏
      //win.setFullScreen(true);

      // 最大化
      win.maximize();

      //配置ESC键退出全屏 ESC
      globalShortcut.register("Alt+CommandOrControl+Q", () => {
        win.setFullScreen(false);
      });

      // 配置设置快捷键
      globalShortcut.register("Alt+CommandOrControl+S", () => {
        win.webContents.send("asynchronous-message", "123");
      });

      // ctrl_alt_f 打开全屏设置
      globalShortcut.register("Alt+CommandOrControl+F", () => {
        win.setFullScreen(true);
      });

      // 主进程缩小窗口
      ipcMain.on("window-min", function() {
        // 收到渲染进程的窗口最小化操作的通知,并调用窗口最小化函数,执行该操作
        win.minimize();
      });

      // ctrl_alt_i 手动打开开发者工具
      globalShortcut.register("Alt+CommandOrControl+I", () => {
        win.webContents.openDevTools({
          mode: "bottom",
        });
      });

      // 获取安装地址
      // globalShortcut.register('Alt+CommandOrControl+P', () => {
      //     win.webContents.send("asynchronous-message", path.dirname(app.getPath('exe')));
      // })

      // 手动打开开发者工具
      // ipcMain.on('open-dev', function () { // 收到渲染进程的窗口最小化操作的通知,并调用窗口最小化函数,执行该操作
      //     win.webContents.openDevTools({
      //         mode: 'bottom'
      //     })
      // })

      // 设置顶部菜单
      // 自定义一些菜单
      const appMenuTemplate = [
        {
          label: "窗口",
          submenu: [
            {
              label: "打开全屏",
              click: () => {
                win.setFullScreen(true);
              },
            },
            {
              label: "退出全屏",
              click: () => {
                win.setFullScreen(false);
              },
            },
          ],
        },
        {
          label: "设置",
          submenu: [
            // {
            //   label: "设置首页",
            //   click: () => {
            //     win.webContents.send("asynchronous-message", "123");
            //   },
            // },
            {
              label: "强制刷新",
              role: "forceReload",
            },
            {
              label: "退出",
              role: "quit",
            },
            {
              label: "开发者选项",
              click: () => {
                win.webContents.openDevTools({
                  mode: "bottom",
                });
              },
            },
          ],
        },
      ];

      const menu = Menu.buildFromTemplate(appMenuTemplate);
      Menu.setApplicationMenu(menu);

      // 窗口关闭的监听
      win.on("closed", (event) => {
        win = null;
      });

      // 点击关闭
      win.on("close", (event) => {
        const closeWinFlagValue = dialog.showMessageBoxSync(win, {
          type: "info",
          buttons: ["最小化到托盘", "直接退出", "取消"],
          title: "提示",
          message: "确定要退出吗?",
          defaultId: 0,
          cancelId: 2,
        });
        console.log("closeWinFlagValue", closeWinFlagValue);
        event.preventDefault();
        if (closeWinFlagValue === 0) {
          // 托盘对象
          var appTray = null;
          // 系统托盘右键菜单
          var trayMenuTemplate = [
            {
              label: "显示",
              click: function() {
                !win.isVisible() ? win.show() : null;
              },
            },
            {
              label: "退出",
              click: function() {
                app.quit();
              },
            },
          ];
          win.hide();
          // 系统托盘图标目录 path.join(__static, './logo_1.ico')
          let trayIcon = path.join(__dirname, "./favicon.ico");

          appTray = new Tray(trayIcon);

          // 图标的上下文菜单
          const contextMenu = Menu.buildFromTemplate(trayMenuTemplate);

          // 设置此托盘图标的悬停提示内容
          appTray.setToolTip("上海局高铁机务管理智能评价系统");

          // 设置此图标的上下文菜单
          appTray.setContextMenu(contextMenu);

          // 单击击托盘显示隐藏
          appTray.on("click", () => {
            win.isVisible() ? win.hide() : win.show();
            // 关闭托盘显示
            appTray.destroy();
            appTray = null;
          });
        } else if (closeWinFlagValue === 1) {
          app.exit();
        } else if (closeWinFlagValue === 2) {
          win.focus();
          win.show();
        }
      });

      // 设置托盘
      // Exit cleanly on request from parent process in development mode.

      if (process.platform === "win32") {
        /* process.on('message', (data) => {
            if (data === 'graceful-exit') {
                app.quit()
            }
        }) */
      } else {
        process.on("SIGTERM", () => {
          app.quit();
        });
      }

      // D:/dev_tools/MIES
      //console.log('读取本地文件 == ', res);
      // let socketPath = exePath + "/WebMiddleware.exe";
      // //let child = cp.spawn(socketPath, [res.ip, res.port])
      // cp.exec(`${socketPath} ${res.ip} ${res.port}`, (err, stdout, stderr) => {
      //   console.log("err, stdout, stderr", err, stdout, stderr);
      // });

      // 向vue发送配置的wsip和端口
      let ws_path = `wss://${res.ws_ip}:${res.ws_port}`;
      const http = require("http"); // 创建服务器对象
      const server = http.createServer();
      const closeServer = () => {
        sockets.forEach(function(socket) {
          socket.destroy();
        });
        server.close(function() {
          console.log("close server!");
        });
      };
      server.listen(res.local_port); // 对错误进行捕获
      server.on("error", (err) => {
        if (err.code == "EADDRINUSE") {
          // 如果目标端口被占用将使用
          // NodeJS 随机分配的端口号
          server.listen(0);
        }
      }); // 在成功监听后,向终端输出被监听的端口号
      server.on("listening", () => {
        console.log(
          "【HTTP Server is running at http://127.0.0.1:" +
            server.address().port +
            " 】"
        );
      });
      server.on("connection", function(socket) {
        sockets.push(socket);
        //console.log('sockets', sockets);
        socket.once("close", function() {
          sockets.splice(sockets.indexOf(socket), 1);
        });
      });
      server.on("request", function(req, res) {
        const url = req.url;
        if (url === "/getWsPath") {
          res.setHeader("content-type", "application/json");
          res.end(ws_path);
          closeServer();
        } else {
          res.writeHeader(404);
          res.end("404 not found");
          closeServer();
        }
      });
    }
  });
}

至此就可以完成读取本地文件,获取配置信息功能。

第三,完成缩放功能

需求要求实现和浏览器一样,ctrl加上鼠标滚轮,可以完成页面的缩放,具体代码如下:

let level = 0;
      // 缩放
      win.webContents.on('zoom-changed',(e, zoomDirection)=>{
        if (zoomDirection === 'in') {
          level = level >= 3 ? level : level += 0.2
        } else {
          level = level <= -3 ? level : level -= 0.2
        }
        win.webContents.setZoomLevel(level)
      })

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/504918.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯 本质上升序列

题目描述: 小蓝特别喜欢单调递增的事物。 在一个字符串中&#xff0c;如果取出若干个字符&#xff0c;将这些字符按照在字符串中的顺序排列后是单调递增的&#xff0c;则成为这个字符串中的一个单调递增子序列。 例如&#xff0c;在字符串 lanqiao 中&#xff0c;如果取出字符…

二维码门楼牌管理应用平台建设:构建智慧社区新生态

文章目录 前言一、二维码门楼牌管理应用平台概述二、公益报名功能的实现方式三、二维码门楼牌管理应用平台在智慧社区建设中的作用四、结论与展望 前言 随着科技的快速发展&#xff0c;智慧城市建设已成为现代城市管理的重要方向。二维码门楼牌管理应用平台作为智慧社区建设的…

算法系列--动态规划--特殊的状态表示--分析重复子问题

&#x1f495;"轻舟已过万重山!"&#x1f495; 作者&#xff1a;Lvzi 文章主要内容&#xff1a;算法系列–算法系列–动态规划–特殊的状态表示–分析重复子问题 大家好,今天为大家带来的是算法系列--动态规划--特殊的状态表示--分析重复子问题 一.组合总数IV 链接…

Mybatis的动态SQL~

MyBatis有一个强大特性就是它的动态SQL。在实际项目开发中&#xff0c;经常需要根据不同条件拼接SQL语句&#xff0c;拼接时还要确保不能忘了必要的空格&#xff0c;有时候还要注意省掉列名列表最后的逗号...等等。在使用JDBC 或其他类似持久层框架操作数据库时&#xff0c;处理…

探索----------------阿里云

目录 一、阿里云四大件 1、云服务器ECS 2、云数据库RDS 3、负载均衡SLB 4、对象存储OSS 5、其他的云计算产品 1&#xff09;内容分发网络CDN 2&#xff09;专有网络 VPC 二、linux发行版本 三、你平时对系统会怎么优化&#xff08;五大负载&#xff09; 1、cpu 使用率…

记一次对Codis的无知引起的逻辑变更

先提前说明&#xff0c;对Codis的无知是因为Codis不支持一些Redis的命令&#xff0c;而这次的逻辑变更&#xff0c;就是因为使用了PUBLISH&#xff0c;而Codis又不支持PUBLISH导致的。 1. 前言 前段时间的一次需求中&#xff0c;因为设计到多个服务的注册问题&#xff0c;在项…

算法整理:排序

快速排序 首先不妨以第一个数为基准数&#xff0c;在一轮遍历后&#xff0c;使基准数左边的数都小于基准数&#xff0c;基准数右边的数都大于基准数。 当然也可以取中间的数为基准数。 void quick_sort(int q[],int l,int r){if(l>r)return;int i l;int j r;int xq[(lr)/…

类的函数成员(二):析构函数

一.定义 析构函数(destructor) 与构造函数相反&#xff0c;当对象结束其生命周期&#xff0c;如对象所在的函数已调用完毕时&#xff0c;系统自动执行析构函数。析构函数往往用来做“清理善后” 的工作。 例如&#xff0c;在建立对象时用new开辟了一片内存空间&#xff0c;dele…

【LeetCode】三月题解

文章目录 [2369. 检查数组是否存在有效划分](https://leetcode.cn/problems/check-if-there-is-a-valid-partition-for-the-array/)思路&#xff1a;代码&#xff1a; [1976. 到达目的地的方案数](https://leetcode.cn/problems/number-of-ways-to-arrive-at-destination/) 思路…

005 高并发内存池_CentralCache设计

​&#x1f308;个人主页&#xff1a;Fan_558 &#x1f525; 系列专栏&#xff1a;高并发内存池 &#x1f339;关注我&#x1f4aa;&#x1f3fb;带你学更多知识 文章目录 前言本文重点一、构建CentralCache结构二、运用慢开始反馈调节算法三、完成向CentralCache中心缓存申请四…

【讲解下Gitea】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

2024.3.30学习笔记

今日学习韩顺平java0200_韩顺平Java_对象机制练习_哔哩哔哩_bilibili 今日学习p295-p314 super关键字 super代表父类的引用&#xff0c;用于访问父类的属性、方法、构造器 super细节和语法 访问父类的属性&#xff0c;但不能访问父类的private属性 super.属性名 访问父类的…

STM32学习笔记(10_2)- I2C通信协议MPU6050简介

无人问津也好&#xff0c;技不如人也罢&#xff0c;都应静下心来&#xff0c;去做该做的事。 最近在学STM32&#xff0c;所以也开贴记录一下主要内容&#xff0c;省的过目即忘。视频教程为江科大&#xff08;改名江协科技&#xff09;&#xff0c;网站jiangxiekeji.com 本期开…

【Java八股学习】Redis持久化 思维导图

说明 文章内容通过学习小林Coding内的优质文章后整理而来&#xff0c;整理成思维导图的方式是为了帮助自己理解、记忆和复习。如若侵权请联系删除&#xff0c;再次对小林Coding内的优质文章表示感谢。参考文章如下&#xff1a; AOF 持久化是怎么实现的&#xff1f;RDB 快照是…

Leaflet使用多面(MultiPolygon)进行遥感影像掩膜报错解决之道

目录 前言 一、问题初诊断 1、山重水复 2、柳暗花明 3、庖丁解牛 4、问题定位 二、解决多面掩膜问题 1、尝试数据修复 2、实际修复 3、最终效果 三、总结 前言 之前一篇讲解遥感影像掩膜实现&#xff1a;基于SpringBoot和Leaflet的行政区划地图掩膜效果实战&#xff0…

CleanMyMac X中文---让Mac焕发新生,Mac优化与清理的终极利器

CleanMyMac X是一款专为Mac用户设计的综合性系统优化工具。通过智能扫描&#xff0c;它能够快速识别并清理Mac磁盘上的垃圾文件、重复文件、无用语言安装包、iTunes缓存、邮件附件等&#xff0c;有效释放磁盘空间&#xff0c;提升Mac电脑的运行速度。此外&#xff0c;CleanMyMa…

【初阶数据结构】——160. 相交链表

文章目录 1. 题目介绍2. 思路1&#xff1a;暴力求解算法思想代码实现 3. 思路2&#xff1a;快慢指针算法思想代码实现 1. 题目介绍 链接: link 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&…

Flutter 全局控制底部导航栏和自定义导航栏的方法

1. 介绍 导航栏在移动应用中扮演着至关重要的角色&#xff0c;它是用户与应用之间进行导航和交互的核心组件之一。无论是简单的页面切换&#xff0c;还是复杂的应用导航&#xff0c;导航栏都能够帮助用户快速找到所需内容&#xff0c;提升用户体验和应用的易用性。 在移动应用…

chatgpt用pygame根据重心坐标 填充三角形

pygame.Surface.set_at(screen, (int(w), int(h)), (int(255zhongxina),int(255zhongxinb),int(255zhongxinc))) 颜色是由三个重心坐标权重abc255求出的 import pygame from pygame.locals import * import sys import mathpygame.init()width, height 800, 600 screen pyga…

关于 C/C++ 1Z(17)开源项目 openppp2 协同程式切换工作流

下述为开源项目 openppp2&#xff08;github&#xff09;构建工作在 C/C 17 的 stackful 有栈协同程式的工作流切换示意图&#xff1a; 在 openppp2 之中采用人工手动方式管理协同程式之间的切换&#xff0c;每个中断过程只是保存线程栈信息&#xff08;如寄存器、当前#PC EIP&…