如何在win10中创建击键监视器窗口服务?

时间:2018-04-18 23:59:35

标签: python windows-services keystroke

我想记录相关密钥的印刷时间和发布时间,并将此信息写入后台文件。我用python和pack python脚本实现它到windows可执行文件中。当我双击这个可执行文件时,它正常工作,但是,当我使用"sc.exe"工具将其转换为Windows服务时,它不起作用。

我已经尝试了"win32serviceutil.ServiceFramework"(Windows服务的python api),它也无效。

1 个答案:

答案 0 :(得分:0)

@Peter Haddad

我想使用Keyrecorder_Win.py来记录keystorke信息,并使用ServiceLauncher.py或“sc.exe”将“Keyrecorder”包装到Windows服务中。 “它不起作用”可分为2种情况:

  • 情况1:

    当我执行Keyrecorder_win.py时,它正常工作,但是当我将Windows置入睡眠状态并稍后将其唤醒时,它无法再将按键信息写入文件。

  • 情况2:

    当我将python脚本包装到Windows服务并在后台启动服务时,它也无法将信息写入文件。

我的目的是在背景上运行此监控程序,并希望即使我将计算机从睡眠状态唤醒也能正常工作。

这是我的代码:

Keyrecorder_Win.py:

#!/usr/bin/env python
#coding: utf-8
import pythoncom
import pyHook
import time
import os
import re 
press_stack = []
release_stack = []
class Keyrecorder(object):
    def __init__(self):
        self.path_result_dir = os.path.join(os.getcwd(), "Result")
        if not os.path.exists(self.path_result_dir):
            os.mkdir(self.path_result_dir)

    def Time2Date(self, sec):
        time_struct = time.localtime(sec)
        time_string = time.strftime('%Y-%m-%d', time_struct)
        return time_string

    def onKeyboardEvent(self, event):
        time_string = self.Time2Date(time.time())
        fp = os.path.join(self.path_result_dir, time_string + ".txt")

        if not os.path.exists(fp):
            fobj = open(fp, "w")
        else:
            fobj = open(fp, "a+")
        press_time = -1
        release_time = -1
        event_type = event.MessageName # press or release
        event_key = event.Key # related key

        if event_type == "key down":
            press_time = int(time.time()*10**6)
            press_stack.append((event_key, press_time))
        elif event_type == "key up":
            release_time = int(time.time()*10**6)
            release_stack.append((event_key, release_time))

        len1 = len(press_stack)
        len2 = len(release_stack)
        if len1 > 0 and len1 == len2:
            is_reverse = press_stack[0][0] != release_stack[0][0]
            # press key in turn,but release key in reverse order
            if len1 == 2 and is_reverse:
                while len(release_stack) > 0:
                    p = press_stack.pop(0)
                    r = release_stack.pop()
                    duration = r[1] - p[1]
                    record = "%s\t%d\t%d\t%d\n" % (p[0], p[1], r[1], duration)
                    fobj.write(record)
                    fobj.flush()

            # press and release key in turn 
            elif len1 >= 1 and not is_reverse:
                while len(release_stack) > 0:
                    p = press_stack.pop(0)
                    r = release_stack.pop(0)
                    duration = r[1] - p[1]
                    record = "%s\t%d\t%d\t%d\n" % (p[0], p[1], r[1], duration)
                    fobj.write(record)
                    fobj.flush()

            # function key firstly be pressed,then other keys be pressed. 
            # other key be released firstly then release function key. 
            elif len1 > 2 and is_reverse:
                p = press_stack.pop(0)
                r = release_stack.pop()
                duration = r[1] - p[1]
                record = "%s\t%d\t%d\t%d\n" % (p[0], p[1], r[1], duration)
                fobj.write(record)
                fobj.flush()

                while len(release_stack) > 0:
                    p = press_stack.pop(0)
                    r = release_stack.pop(0)
                    duration = r[1] - p[1]
                    record = "%s\t%d\t%d\t%d\n" % (p[0], p[1], r[1], duration)
                    fobj.write(record)
                    fobj.flush()
        if fobj and not fobj.closed:
            fobj.flush()
            fobj.close()

        return True

    def record(self):
        pythoncom.CoInitialize()
        hm = pyHook.HookManager()
        hm.KeyAll = self.onKeyboardEvent
        hm.HookKeyboard()
        pythoncom.PumpMessages()
        pythoncom.CoUninitialize()

def main():
    kr = Keyrecorder()
    kr.record()


if __name__ == '__main__':
    main()

ServiceLauncher.py:

#!/usr/bin/env python
#coding: utf-8

import win32serviceutil
import win32service
import win32event
import winerror
import servicemanager
import os
import sys

class ServiceLauncher(win32serviceutil.ServiceFramework):
    _svc_name_ = 'Keyrecord'
    _svc_display_name_ = 'Keyrecord'
    _svc_description_ = "Keyrecord for windows"

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

    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        win32event.SetEvent(self.hWaitStop)

    def SvcDoRun(self):
        import KeyRecorder_Win
        kr = KeyRecorder_Win.Keyrecorder()
        kr.record()

if __name__=='__main__':
    if len(sys.argv) == 1:
        try:
            evtsrc_dll = os.path.abspath(servicemanager.__file__)
            servicemanager.PrepareToHostSingle(ServiceLauncher)
            servicemanager.Initialize('ServiceLauncher', evtsrc_dll)
            servicemanager.StartServiceCtrlDispatcher()
        except win32service.error, details:
            if details[0] == winerror.ERROR_FAILED_SERVICE_CONTROLLER_CONNECT:
                win32serviceutil.usage()
            else:
                win32serviceutil.HandleCommandLine(ServiceLauncher)