Как создать клавиатуру монитора Windows Services в Win10?

Я хочу записать время нажатия и отпускания соответствующей клавиши и записать эту информацию в файл в фоновом режиме. Я реализую его с помощью Python и упаковываю скрипт Python в исполняемый файл Windows. Когда я дважды щелкаю этот исполняемый файл, он работает нормально, однако, когда я использую "sc.exe" инструмент для преобразования его в службу Windows, он не работает.

Я попробовал "win32serviceutil.ServiceFramework"(Python API Windows Services), это также не работает.

1 ответ

@ Питер Хаддад

Я хочу использовать Keyrecorder_Win.py для записи информации о нажатии клавиш и использовать ServiceLauncher.py или "sc.exe", чтобы обернуть "Keyrecorder" в службу Windows. "Это не работает" можно классифицировать на 2 ситуации:

  • ситуация 1:

    Когда я выполняю Keyrecorder_win.py, он работает нормально, но когда я перехожу в режим сна и запускаю его позже, он больше не может записать информацию о нажатии клавиши в файл.

  • ситуация 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)
Другие вопросы по тегам