使用Electron获取用户信息,监听程序打开,用户退出连接关闭程序【全代码,有图】

使用Electron获取用户信息,监听程序打开,用户退出连接关闭程序【全代码,有图】

效果图

如有其他操作可在代码中自己添加

main.js

js 复制代码
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('node:path');
const os = require('os');
const { exec } = require('child_process');

let intervalId;

const createWindow = () => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        autoHideMenuBar: true,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js'),
        }
    });

    win.loadFile('view/index.html');

    // 确保窗口完全加载后发送用户信息
    win.once('ready-to-show', () => {
        LogsInUser(win);  // 发送登录用户信息
    });
};

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});

app.whenReady().then(() => {
    // 订阅消息
    ipcMain.handle('getWindowsUser', getWindowsUser);

    createWindow();
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow();
    });

    // 每 5 秒获取登录用户信息
    startUserCheck();
});


function getWindowsUser() {
    const userDomain = process.env.USERDOMAIN || 'UNKNOWN_DOMAIN';//用于获取当前用户的域名或工作组名称
    const username = os.userInfo().username; // 获取用户名
    return `${userDomain}---${username}`; // 返回域账号格式
}

function LogsInUser(win) {
    if (win) {
        // 将用户信息发送到前端
        win.webContents.send('LogsInUser', os.userInfo().username);
    };
}


// 启动用户检查函数,每 5 秒执行一次
function startUserCheck() {
    intervalId = setInterval(() => {
        // 每次检查获取当前登录的用户
        getLoggedInUsers();
    }, 5000);
}

// 获取当前登录用户信息并判断其状态
function getLoggedInUsers() {
    const username = os.userInfo().username;

    // 如果 username 为空,退出程序
    if (!username) {
        console.log('Username is empty, exiting...');
        clearInterval(intervalId);
        app.quit();
        return;
    }

    // 使用 Windows 命令检查用户是否连接
    checkUserConnection(username, (isConnected) => {
        if (!isConnected) {
            console.log(`${username} is disconnected, exiting...`);
            clearInterval(intervalId);
            app.quit();
        } else {
            console.log(`Logged in user: ${username} is still connected`);
            const win = BrowserWindow.getAllWindows()[0];
            if (win) {
                win.webContents.send('userLoggedIn', username);
            }
        }
    });
}

// 使用 Windows 命令行检查当前用户连接状态
function checkUserConnection(username, callback) {
    exec('chcp 65001 && qwinsta', { encoding: 'utf8' }, (error, stdout, stderr) => {

        if (error || stderr) {
            return callback(false); // 如果出错,认为用户断开
        }

        // 去除 stdout 中的多余空格和换行符
        const cleanedStdout = stdout.replace(/\s+/g, ' ').trim();

        // 正则表达式匹配当前用户的行,查找状态为 "Active" 或 "Disc" 的用户
        const userPattern = new RegExp(`(\\S+)\\s+(${username})\\s+\\d+\\s+(Active|Disc|Disconnected)`, 'i');

        const matches = cleanedStdout.match(userPattern);

        if (matches && matches[3] === 'Active') {
            callback(true); // 如果用户是活跃状态
        } else {
            callback(false); // 否则认为用户断开
        }
    });
}

preload.js

js 复制代码
const { contextBridge,ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('myApi', {
    getWindowsUser: () => {
        return ipcRenderer.invoke('getWindowsUser')
    },
    userLoggedIn: (callback) => {
        ipcRenderer.on('userLoggedIn', (event, data) => {
            callback(data);
        });
    },
    LogsInUser: (callback) => {
        ipcRenderer.on('LogsInUser', (event, data) => {
            callback(data);
        });
    }
})

render.js

js 复制代码
const btn1 = document.getElementById('btn1')

const logContainer = document.getElementById('logContainer');
const LogsText = document.getElementById('LogsText');


btn1.onclick= async ()=>{
    let data= await myApi.getWindowsUser()
    //获取node的api
    alert(data)
}


// 初始化时设置用户事件监听
myApi.userLoggedIn((data) => {
    const logText = `用户: ${data}, 时间: ${new Date().toLocaleString()}`;
    const logElement = document.createElement('p');
    logElement.textContent = logText;
    logContainer.appendChild(logElement);
});

// 初始化时设置用户事件监听
myApi.LogsInUser((data) => {
    const logText = `用户: ${data}, 时间: ${new Date().toLocaleString()}`;
    const logElement = document.createElement('p');
    logElement.textContent = logText;
    LogsText.appendChild(logElement);
});

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    <title>超级无敌炫酷闪光智能高端产品</title>
    <link rel="stylesheet" href="../style/index.css">
</head>
<body>
<div class="textStyle">
    Hello Electron!
</div>

<div>
    <hr>
    <button id="btn1">获取本机账号信息</button>
    <hr>
    <div id="LogsText">
        日志记录
        <!-- 用户连接与断开信息将在这里显示 -->
    </div>
    <hr>
    <div id="logContainer">
        检测连接
        <!-- 用户连接与断开信息将在这里显示 -->
    </div>
</div>

<script type="text/javascript" src="./render.js" ></script>
</body>
</html>
相关推荐
陈随易6 分钟前
Rust、Golang、MoonBit 编译成 WASM,体积和速度差距有多大?
前端·后端·程序员
IT_陈寒9 分钟前
Python多线程的坑,我居然现在才踩到
前端·人工智能·后端
摇滚侠15 分钟前
方法 A 等方法 B 执行完再执行 叫同步调用还是异步调用 JS 默认是同步调用还是异步调用
开发语言·javascript·ecmascript
触底反弹1 小时前
🔥 字符串算法面试三连击:反转、回文、回文变种,搞懂这三题稳了!
前端·javascript·算法
触底反弹1 小时前
AI Tool Use 深度解析:大模型是如何"突破物理限制"调用外部工具的?
javascript·人工智能·后端
竹林8181 小时前
从 RPC 超时到批量签名:我用 @solana/web3.js 重构了一个 NFT 铸造页面,踩了这些坑
前端·javascript
工业HMI实战笔记2 小时前
工业HMI界面布局“1核2辅”黄金结构,适配90%场景
前端·ui·性能优化·自动化·交互
优雅格子衫2 小时前
TypeScript 类的基本使用小结
javascript·ubuntu·typescript
橘子星2 小时前
从零手写 RAG 语义检索:基于 Node.js 实现轻量级向量搜索
javascript·人工智能
林希_Rachel_傻希希2 小时前
web性能优化之————图片效果
前端·javascript·面试