You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Win10下创建按键监控Windows服务失败求助,Python转服务异常

解决Windows服务运行按键记录脚本失败的问题

兄弟,我之前踩过一模一样的坑!问题出在Windows服务默认的Session 0隔离机制上——这玩意儿是真坑人:你双击exe的时候,程序是在你的用户会话里跑的,能正常访问键盘输入;但转成服务后,它默认跑到Session 0这个和用户桌面完全隔离的系统会话里,根本碰不到你的输入设备,自然就失效了。

下面给你几个可行的解决方案,按推荐程度排序:

方案1:改服务的登录账户为当前用户(最直接)

让服务在你的用户会话里运行,而不是Session 0:

  • 按Win+R输入services.msc打开服务管理器
  • 找到你的按键记录服务,右键→属性→「登录」选项卡
  • 选「此账户」,输入你当前Windows账户的用户名和密码,点确定
  • 重启服务,应该就能正常捕获按键了

如果是用win32serviceutil写的服务代码,安装时直接指定账户更方便:

# 执行这条命令安装服务,替换成你的账户信息
python your_service.py install --username "你的Windows用户名" --password "你的密码"

方案2:用任务计划替代服务(更稳定)

如果不是非要用服务,其实「任务计划程序」是更好的选择——它天生就在用户会话里启动程序,没有Session 0的限制:

  • 打开任务计划程序,创建基本任务
  • 触发器选「当用户登录时」
  • 操作选「启动程序」,选中你的按键记录exe
  • 在「设置」里可以勾选「不管用户是否登录都要运行」(要后台运行的话),记得勾上「使用最高权限运行」
  • 这种方式比服务省心多了,还不容易出权限问题

方案3:修复win32serviceutil的服务代码(非要用服务的话)

如果你铁了心要用服务实现,除了改登录账户,还要确保代码适配服务的生命周期。比如用pynput的话,监听器要在服务启动后正确初始化,还要处理停止信号:

import win32serviceutil
import win32service
import win32event
import servicemanager
from pynput.keyboard import Listener
import time

class KeyLoggerService(win32serviceutil.ServiceFramework):
    _svc_name_ = "KeyLoggerService"
    _svc_display_name_ = "按键记录服务"
    _svc_description_ = "捕获按键按下与释放时间并写入文件"

    def __init__(self, args):
        win32serviceutil.ServiceFramework.__init__(self, args)
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)
        self.running = True
        self.listener = None

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.running = False
        if self.listener:
            self.listener.stop()
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE,
                              servicemanager.PYS_SERVICE_STARTED,
                              (self._svc_name_, ''))
        
        # 定义按键回调
        def log_key(action, key):
            try:
                with open("key_log.txt", "a", encoding="utf-8") as f:
                    f.write(f"{action}: {str(key)} | 时间: {time.ctime()}\n")
            except Exception as e:
                # 可以把错误写到系统日志里
                servicemanager.LogErrorMsg(f"日志写入失败: {str(e)}")

        # 启动监听器
        self.listener = Listener(
            on_press=lambda k: log_key("按下", k),
            on_release=lambda k: log_key("释放", k)
        )
        self.listener.start()
        
        # 等待停止信号,别阻塞服务
        while self.running:
            win32event.WaitForSingleObject(self.hWaitStop, 1000)

if __name__ == '__main__':
    win32serviceutil.HandleCommandLine(KeyLoggerService)

⚠️ 重点:安装这个服务时必须指定你的用户账户,不然还是会跑到Session 0,捕获不到按键。

避坑提醒

  • 别用「本地系统账户」跑服务!Windows 7之后默认禁用了系统账户的桌面交互权限,而且就算开了,也还是在Session 0,没用
  • 按键记录程序必须在用户会话里运行,Session 0是绝对碰不到用户输入的
  • 用pyinstaller打包时,记得用pyinstaller --onefile your_script.py,确保所有依赖都被打包进去,避免服务运行时找不到库

内容的提问来源于stack exchange,提问作者Bug Phh

火山引擎 最新活动