electron提升软件运行权限,以管理员权限运行

news2025/2/23 19:19:47

大家有任何想法,都可以联系博主沟通。

本系列为实战文章,最终实现的桌面工具软件,获取方式:百度网盘地址:https://pan.baidu.com/s/1yrl0jYpti7QCn8CHBRT2lw?pwd=1234


正文开始

  • 前言
  • 一、提升electron运行权限的三种方式
  • 二、何种场景可能需要提升权限
  • 三、具体实现
    • 3.1 检查权限
    • 3.2重启electron软件
    • 3.3服务管理
  • 四、总结


前言

在桌面软件使用场景,有很多需要管理员权限的功能,比如说操作注册表、操作服务等。博主前面有一篇文章是介绍,如何使用electron-builder打包软件,设置安装electron软件时,主动提升权限。

这样确实可以解决一部分问题,但是很多用户内心是反感在安装阶段,就为软件赋予管理员权限的。这就要求我们的软件在提升权限方面,更加灵活。

除了在electron-builder的配置文件中配置:“allowElevation”:true,我们还可以通过其他方式,实现普通功能以正常权限启动,特殊功能需要管理员权限时,提醒用户重启软件。


一、提升electron运行权限的三种方式

  1. electron-builder中配置"allowElevation":true。具体实现方案参考,请搜索关键字“electron-builder允许安装时请求提升权限 中二少年学编程”。此方式,不能为绿色版软件提供支撑,也易造成用户安装软件时的反感。
  2. 每次启动electron软件时,右键选择以管理员方式启动。此方式完全借助用户行为提升软件权限,对用户十分不友好。
  3. 当需要提升权限时,提醒用户当前用户管理权限不足,并便捷地以管理员权限重启软件。本文主要介绍此方式。

二、何种场景可能需要提升权限

修改注册表、修改系统级环境变量、修改系统级的配置文件、管理服务等场景下,都可能需要更高等级的用户权限——管理员权限。

本文以管理服务(windows环境)为例,详细介绍,如何便捷地为electron提升运行权限。

需求描述:

  1. 开发服务管理功能,将jar包以服务的形式运行,并提供创建服务、启动服务、停止服务、删除服务等功能。如图:
    在这里插入图片描述
    2.创建服务、删除服务、启动服务等功能需要管理员权限,当检测到当前electron软件运行权限不足,则重启软件,提升权限,如图:
    在这里插入图片描述
    点击重启后,会弹出一个系统提示框,提示是否以管理员权限重启软件。

3.重启后,重新创建服务,则创建成功,在服务列表查看服务是否存在,验证效果。如图:

在这里插入图片描述
在这里插入图片描述
出现名称为“222”的服务,说明创建成功。

三、具体实现

3.1 检查权限

windows环境检查当前用户权限是否为管理员权限,有很多种方式,比较常用的是输入命令行:net session。如果报错,则为普通权限,不报错则为管理员权限。这个方案在大多数场景下都可用。

net session检查权限的方式有一个弊端,就是要求必须开启了Server服务。如果禁用Server:
在这里插入图片描述
禁用server后,无论是否以管理员权限运行命令行,都会报错——没有启动服务器服务:
在这里插入图片描述
而某些安全要求比较高的windows服务器,是不允许开通server服务的,所以上面的方法只能被舍弃。如果读者确定自己开发的软件不会应用与服务器,或者运行环境不会强制要求关闭server服务,则完全可以使用上面的命令行检查用户权限。

另一种比较稳定的判断权限方法是:openfiles。在普通用户权限和管理员权限,分别运行openfiles,如图:在这里插入图片描述

在这里插入图片描述
可以得出结论,如果运行命令行报错,则是普通权限,如果没有报错,则为管理员权限。

所以,我们判断权限的代码如下:

/**
 * 判断是否是管理员权限*/
const isAdmin=exports.isAdmin=()=>{
    return new Promise((resolve) => {
        if (process.platform === 'win32') {
            exec('openfiles', (err) => {
                if (err) {
                    resolve(false); // 不是管理员
                } else {
                    resolve(true); // 是管理员
                }
            });
        }

    });
}

3.2重启electron软件

当发现当前环境不是管理员权限,我们需要以管理员权限,重启electron软件。

核心方案是:使用 PowerShell 提升权限重启应用:Start-Process -FilePath 你的electron可执行程序地址 -ArgumentList 你的参数 -Verb RunAs

代码如下:

/**
 * 提升权限,重启应用软件*/
exports.restartAppAsAdmin=async ()=>{
    if (process.platform === 'win32') {
        const appPath = app.getPath('exe'); // 获取当前应用的可执行文件路径
        const args = process.argv.slice(1); // 获取当前应用的启动参数
        // 将参数转换为 PowerShell 的字符串数组格式
        const argsString = args.map(arg => `"${arg}"`).join(',');
        console.log(argsString);
        const ArgumentList=argsString?` -ArgumentList ${argsString}`:''
        // Windows:使用 PowerShell 提升权限重启应用
        const command = `Start-Process -FilePath "${appPath}" ${ArgumentList} -Verb RunAs`;
        exec(`powershell -Command "${command}"`, (err) => {
            if (err) {
                console.error('重启失败:',Buffer.from(err.message, 'binary').toString('utf16le') );
                return {
                    success:false,
                    msg:Buffer.from(err.message, 'binary').toString('utf16le')
                }
            } else {
                console.log('重启成功');
                app.quit(); // 退出当前应用
                return true
            }
        });
    }
}

上面就是重启应用的全部代码,关键代码都写了注释,读者请自行研读。

3.3服务管理

对服务的增删改查等管理功能,是基于nssm实现的,这部分并不难,也不是本文内容的重点,所以仅仅粘贴一下代码,读者有需要可自行参阅。

/**
 * 为可执行的组件创建服务*/
const path = require('path')
const {spawn: spawn} = require('child_process')

class ServiceOperate {
    constructor(option = {}) {
        this.comPath=option.comPath || ''
        this.serviceName=option.serviceName || ''
        this.spawnCommand = path.join(process.env.ElectronPlugins, 'nssm/win64/nssm')
        this.serviceCmdArgs = null
    }
    init(option){
        this.comPath = option.comPath
        this.serviceName = option.serviceName
        return this
    }

    /**
     * 通过服务名和运行命令,创建服务*/
    createService() {
        // 构建NSSM命令
        // this.serviceCmdArgs = `install ${this.serviceName} "javaw -jar ${this.comPath}"`
        this.serviceCmdArgs = [
            'install',
            this.serviceName,
            'F:\\cnde-deploy\\jdk1.8.0_202\\jre\\bin\\javaw',
            '-jar',
            this.comPath
        ]
        // 判断是否以管理员身份运行
        return this.execute(this.spawnCommand,this.serviceCmdArgs)
    }

    /**
     * 根据服务名删除服务*/
    removeService() {
        this.serviceCmdArgs = [
            'remove',
            this.serviceName,
            'confirm'
        ]

        return this.execute(this.spawnCommand,this.serviceCmdArgs)

    }
    /**
     * 根据服务名查询服务*/
    checkService() {
        const spawnCommand = 'sc'
        this.serviceCmdArgs = [
            'query',
            this.serviceName
        ]
        return this.execute(spawnCommand,this.serviceCmdArgs).then(res=>{
            const isRunning = res.stdout.includes('RUNNING')
            return {...res,isRunning}
        }).catch(err=>{
            return err
        })

    }
    /**
     * 根据服务名启动服务*/
    startService() {
        this.serviceCmdArgs = [
            'start',
            this.serviceName
        ]
        return this.execute(this.spawnCommand,this.serviceCmdArgs)
    }

    /**
     * 根据服务名停止服务*/
    stopService(){
        const spawnCommand = 'sc'
        this.serviceCmdArgs = [
            'stop',
            this.serviceName
        ]
        return this.execute(spawnCommand,this.serviceCmdArgs)
    }
    execute(spawnCommand,serviceCmdArgs) {
        return new Promise((resolve, reject) => {
            if(!this.serviceName){
                return reject({success:false,code: 1, stdout: '', stderr: '服务名称不能为空'})
            }
            const child = spawn(spawnCommand, serviceCmdArgs);
            let stdoutData = '';
            let stderrData = '';

            child.stdout.on('data', (data) => {
                console.log('stdout:', data.toString());
                stdoutData += data.toString()
            });

            child.stderr.on('data', (data) => {
                console.log('stderr:', data.toString());

                stderrData +=Buffer.from(data, 'binary').toString('utf16le')

            });

            child.on('close', (code) => {
                console.log(`Child process exited with code ${code} ${child.pid}`);
                if (code === 0) {
                    resolve({success:!stderrData,stdout: stdoutData, stderr: stderrData});
                } else {
                    console.log(stderrData)

                    reject({success:false,code, stdout: stdoutData, stderr: stderrData});
                }

            });
        })


    }

}
module.exports=ServiceOperate

关于服务的管理功能比较小众,如果私信的同学多了,可能会重开一篇文章介绍。

四、总结

electron软件提升权限为管理员权限有两种方式:

  1. electron-builder配置allowElevation参数,在软件安装时提升权限。
  2. 在软件使用时,通过powershell运行命令行,以管理员权限重启应用。

在软件使用时,提升软件权限的三步:

  1. 通过命令行,判断当前权限是否为管理员权限。
  2. 通过powershell提升权限,重启软件。

本部分仍可优化的功能点:
提升权限重启软件时,可以通过传递参数,告知新启动的软件一些关键信息:比如重启前页面的一些缓存信息、重启前软件的路由信息等。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安科瑞能源物联网平台助力企业实现绿色低碳转型

安科瑞顾强 随着全球能源结构的转型和“双碳”目标的推进,能源管理正朝着智能化、数字化的方向快速发展。安科瑞电气股份有限公司推出的微电网智慧能源管理平台(EMS 3.0),正是这一趋势下的创新解决方案。该平台集成了物联网&…

Spring Boot 中使用 @Transactional 注解配置事务管理

事务管理是应用系统开发中必不可少的一部分。Spring 为事务管理提供了丰富的功能支持。Spring 事务管理分为编程式和声明式的两种方式。编程式事务指的是通过编码方式实现事务;声明式事务基于 AOP,将具体业务逻辑与事务处理解耦。声明式事务管理使业务代码逻辑不受污…

动态链接器(九):.init和.init_array

ELF文件中的.init和.init_array段是程序初始化阶段的重要组成部分,用于在main函数执行前完成必要的初始化操作。 1 .init段和.init_array 段 1.1 作用 .init段包含编译器生成的初始化代码,通常由运行时环境(如C标准库的启动例程&#xff0…

RT-Thread+STM32L475VET6——TF 卡文件系统

文章目录 前言一、板载资源二、具体步骤1.打开CubeMX进行USB配置1.1 使用外部高速时钟,并修改时钟树1.2 打开SPI1,参数默认即可(SPI根据自己需求调整)1.3 打开串口,参数默认1.4 生成工程 2.配置SPI2.1 打开SPI驱动2.2 声明使用SPI…

[论文解析]OmniRe: Omni Urban Scene Reconstruction

OmniRe: Omni Urban Scene Reconstruction 论文地址:https://arxiv.org/abs/2408.16760 代码地址:https://github.com/ziyc/drivestudio 项目地址:https://ziyc.github.io/omnire/ 论文解读 总结 这篇论文代表了一种重建的方向&#xff0…

【微服务优化】ELK日志聚合与查询性能提升实战指南

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

Docker实战-使用docker compose搭建博客

docker run 部署 创建blog网络 [rootk8s-master ~]# docker network create blog 8f533a5a1ec65eae3f98c0ae5a76014a3ab1bf3c087ad952cdc100cc7a658948 [rootk8s-master ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 8f533a5a1ec6 blog bridge …

【JT/T 808协议】808 协议开发笔记 ② ( 终端注册 | 终端注册应答 | 字符编码转换网站 )

文章目录 一、消息头 数据1、消息头拼接2、消息 ID 字段3、消息体属性 字段4、终端手机号 字段5、终端流水号 字段 二、消息体 数据三、校验码计算四、最终计算结果五、终端注册应答1、分解终端应答数据2、终端应答 消息体 数据 六、字符编码转换网站 一、消息头 数据 1、消息头…

51单片机学习之旅——定时器

打开软件 1与其它等于其它,0与其它等于0 1或其它等于1,0或其它等于其它 TMODTMOD&0xF0;//0xF01111 0000进行与操作,高四位保持,低四位清零,高四位定时器1,低四位定时器0 TMODTMOD|0x01;//0x010000 0…

hot100_139. 单词拆分

hot100_139. 单词拆分 思路 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。 示例 1: 输入:…

SQLMesh 系列教程7- 详解 seed 模型

SQLMesh 是一个强大的数据建模和管道管理工具,允许用户通过 SQL 语句定义数据模型并进行版本控制。Seed 模型是 SQLMesh 中的一种特殊模型,主要用于初始化和填充基础数据集。它通常包含静态数据,如参考数据和配置数据,旨在为后续的…

windows11那些事

一.windows11简介 Windows11是‌微软公司于2021年发布的桌面端操作系统,它带来了许多新的功能和改进,旨在提升用户体验和工作效率。以下是一些关于Windows 11的基础知识和使用技巧: ‌‌通用搜索:通过任务栏上的搜索或按Windows…

VividTalk:南京大学、阿里巴巴等机构联合研发的开源3D说话人生成框架

目录 一、前言二、项目概述三、技术架构四、优势特点五、性能评估六、应用场景七、结论与展望 一、前言 在当今人工智能飞速发展的时代,人机交互的方式正不断创新和优化。VividTalk作为南京大学、阿里巴巴、字节跳动和南开大学联合开发的一项开创性技术&#xff0c…

pyside6学习专栏(三):自定义QLabel标签扩展类QLabelEx

标签是界面设计中最常用的控件,本文演示了如何基于PySide6的QLabex控件类扩展定义QLabelEX类,以实现更少的编码完成各种图像、彩色文本、动画的加载和显示,丰富界面显示 本示例演示了QLabel和其扩展类QLabelEx分别显示文本、图像、动画的使用…

后“智驾平权”时代,谁为安全冗余和体验升级“买单”

线控底盘,正在成为新势力争夺下一个技术普及红利的新赛点。 尤其是进入2025年,比亚迪、长安等一线传统自主品牌率先开启高阶智驾的普及战,加上此前已经普及的智能座舱,舱驾智能的「科技平权」进一步加速行业启动「线控底盘」上车窗…

springboot408-基于Java的樱洵宾馆住宿管理系统(源码+数据库+纯前后端分离+部署讲解等)

💕💕作者: 爱笑学姐 💕💕个人简介:十年Java,Python美女程序员一枚,精通计算机专业前后端各类框架。 💕💕各类成品Java毕设 。javaweb,ssm&#xf…

EasyRTC:基于WebRTC与P2P技术,开启智能硬件音视频交互的全新时代

在数字化浪潮的席卷下,智能硬件已成为我们日常生活的重要组成部分,从智能家居到智能穿戴,从工业物联网到远程协作,设备间的互联互通已成为不可或缺的趋势。然而,高效、低延迟且稳定的音视频交互一直是智能硬件领域亟待…

鸿蒙NEXT应用App测试-通用测试

注意:大家记得学完通用测试记得再学鸿蒙专项测试 https://blog.csdn.net/weixin_51166786/article/details/145768653 注意:博主有个鸿蒙专栏,里面从上到下有关于鸿蒙next的教学文档,大家感兴趣可以学习下 如果大家觉得博主文章…

transfmer学习认识

整体架构 1.自注意机制 1.1.softmax 在机器学习和深度学习中,softmax 函数是一个常用的激活函数,用于将一个向量转换为一个概率分布。softmax 函数的公式如下: ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/35c158988402498ba6…

人工智能(AI)的不同维度分类

人工智能(AI)的分类 对机器学习进行分类的方式多种多样,可以根据算法的特性、学习方式、任务类型等不同维度进行分类这些分类都不是互斥的: 1、按数据模态不同:图像,文本,语音,多态等 2、按目标函数不同:判别式模型…