为什么 pythoncom.pumpmessages() 停止工作?

why does pythoncom.pumpmessages() stop working?

所以我正在编写一个记录击键的程序,在我点击离开程序框之前,它工作得很好。当我像小娜一样点击浏览器并开始打字时,它记录了几笔然后完全停止了。它也没有抛出任何错误,所以我不知道如何调试它。

def run(self):
    hm = pyHook.HookManager()
    hm.KeyDown = self.OnKeyboardEvent
    hm.HookKeyboard()
    pythoncom.PumpMessages()

def OnKeyboardEvent(self,event):
        ch=chr(event.Ascii)
        #print [ch]
        if ch in '\x00\x08':
            val='/*'+event.Key+'*/'
            if (val!=self.prev or ch=='\x08') and 'Capital' not in val:
                print val,
                self.writetofile(str(val))
                data=shelve.open('loggerinfo')
                data['strokes']=data['strokes'].append(val)
                data.close()
                self.prev=val
        else:
            self.prev=ch
            char=None
            if ch=='\r':
                char='/*return*/'
            elif ch=='\t':
                char='/*tab*/'
            else:
                char=ch
            if char!=None:
                print char,
                self.writetofile(str(char))
                data=shelve.open('loggerinfo')
                data['strokes']=data['strokes'].append(char)
                data.close()
        return True

我不确定问题出在哪里,因为它不会引发错误。

问题是您的回调函数 OnKeyBoardEvent 需要 return True/False 才能将事件传播到系统的其余部分。这是因为pyHook是一个很底层的拦截器。

正如我最近发现的那样,如果您的函数花费太长时间 return 到 True/False,pyHook 将完全停止拦截按键。因此,您应该做的是立即设置线程和 return True。这将使您想执行的任何操作异步执行。

类似下面的内容。您可能需要查看锁以确保 shelve 不会同时被多个线程访问。

import threading    

def run(self):
    hm = pyHook.HookManager()
    hm.KeyDown = self.OnKeyboardEvent
    hm.HookKeyboard()
    pythoncom.PumpMessages()

def ActOnEvent(event):
    ch=chr(event.Ascii)
    #print [ch]
    if ch in '\x00\x08':
        val='/*'+event.Key+'*/'
        if (val!=self.prev or ch=='\x08') and 'Capital' not in val:
            print val,
            self.writetofile(str(val))
            data=shelve.open('loggerinfo')
            data['strokes']=data['strokes'].append(val)
            data.close()
            self.prev=val
    else:
        self.prev=ch
        char=None
        if ch=='\r':
            char='/*return*/'
        elif ch=='\t':
            char='/*tab*/'
        else:
            char=ch
        if char!=None:
            print char,
            self.writetofile(str(char))
            data=shelve.open('loggerinfo')
            data['strokes']=data['strokes'].append(char)
            data.close()    

def OnKeyboardEvent(self,event):
    threading.Thread(target=ActOnEvent, args=(event,)).start()
    return True