📜  用户不存在时关闭计算机的 python 程序 - Python (1)

📅  最后修改于: 2023-12-03 15:27:12.796000             🧑  作者: Mango

让 Python 程序可以拦截计算机关闭操作

当计算机即将关闭时,操作系统会向所有运行中的程序发送关闭信号,如果你的 Python 程序正在运行,系统会询问你是否愿意保存进度并退出程序。但有时候,你希望程序可以拦截这个关闭操作,等待某些操作完成后再关闭计算机,本文将介绍如何实现这个功能。

实现思路

我们可以使用 win32api 模块中的 SetConsoleCtrlHandler 函数来注册一个关闭事件处理程序。当操作系统收到关闭信号时,会自动调用这个函数指定的处理程序。我们可以在处理程序中检查当前用户是否存在,如果用户不存在,就拒绝关闭计算机,等到用户重新登录后再关闭。

完整代码实现如下:

import win32api
import win32con
import win32security
import os

# 定义关闭事件处理程序
def on_close(event):
    # 如果当前不存在用户
    if not is_user_logged_on():
        # 拒绝关闭操作
        print("用户不存在,无法关闭计算机。")
        # 返回 True 阻止关闭操作
        return True
    # 否则允许关闭操作
    return False

# 判断当前是否存在用户
def is_user_logged_on():
    # 获取当前登录用户的令牌
    try:
        token_handle = win32security.OpenProcessToken(win32api.GetCurrentProcess(), win32security.TOKEN_QUERY)
        user_sid = win32security.GetTokenInformation(token_handle, win32security.TokenUser)[0]
    except:
        # 如果获取令牌失败,则视为用户不存在
        return False

    # 获取所有已登录用户的令牌
    all_users = win32security.EnumerateLoggedOnUsers()
    # 如果当前用户的 SID 存在于已登录用户的列表中,则返回 True
    for user in all_users:
        if user[0] == user_sid:
            return True
    
    # 否则返回 False
    return False

# 注册关闭事件处理程序
win32api.SetConsoleCtrlHandler(on_close, True)

# 运行程序
while True:
    if input("请输入 quit 退出程序:") == "quit":
        break
代码说明
  • on_close 函数为关闭事件处理程序,该函数接收一个整数参数 event,表示关闭事件类型。如果返回 True,则拒绝关闭计算机;否则,允许关闭计算机。
  • is_user_logged_on 函数用于判断当前是否存在已登录的用户。该函数通过获取当前进程的令牌,然后查询所有已登录用户的令牌列表,判断当前用户的令牌是否存在于列表中,从而判断用户是否存在。
  • 在主函数中,我们通过 win32api.SetConsoleCtrlHandler(on_close, True) 注册了关闭事件处理程序。然后通过一个无限循环等待用户输入,输入 quit 后退出程序。
注意事项

需要注意的是,SetConsoleCtrlHandler 函数仅在 Windows 平台上可用,并且只能拦截一些系统信号,例如 CTRL_C_EVENT (Ctrl + C 组合键)和 CTRL_BREAK_EVENT (Ctrl + Break 组合键)。如果你希望拦截其他系统信号,可以使用 win32api.SetConsoleCtrlHandler(callback, add=True) 函数注册自定义处理程序。

参考资料
  1. SetConsoleCtrlHandler function
  2. GetTokenInformation function
  3. EnumerateLoggedOnUsers function