Search code examples
pythonmouseeventkeypresspywin32pyhook

Runtime error in Python


I was playing around with info I can get from key presses and mouse events in python and everything seems to work except when I quit the program I get this error.

runtime error R6031 - Attempt to initialize the CRT more than once. This indicates a bug in your application.

Here is my code not that it only happens when I press 'q' and the program quits.

import pythoncom, pyHook, sys
def OnMouseEvent(event):
    # called when mouse events are received
    print 'MessageName:',event.MessageName
    print 'Message:',event.Message
    print 'Time:',event.Time
    print 'Window:',event.Window
    print 'WindowName:',event.WindowName
    print 'Position:',event.Position
    print 'Wheel:',event.Wheel
    print 'Injected:',event.Injected
    print '---'
    return True

def OnKeyboardEvent(event):
    print "Message Name: ", 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 chr(event.Ascii) == 'q':
        sys.exit()
    return True

hm = pyHook.HookManager()
hm.KeyDown = OnKeyboardEvent
hm.MouseDown = OnMouseEvent
hm.HookKeyboard()
hm.HookMouse()
pythoncom.PumpMessages()

Thanks in advance for the help!


Solution

  • You have to "unhook" the hooks that you created to do a proper exit.

    To terminate the "pythoncom.PumpMessages()" ever-lasting-loop:

        if chr(event.Ascii) == 'q':
            ctypes.windll.user32.PostQuitMessage(0)
    

    The following code works correctly on Windows 7 with Python 2.7.6. I haven't yet figured out how to make it work under Python 3.4, but I'll be back when I know!

    import pythoncom, pyHook
    import ctypes
    import sys
    
    
    def OnMouseEvent(event):
        # called when mouse events are received
        print('MessageName:', event.MessageName)
        print('Message:', event.Message)
        print('Time:', event.Time)
        print('Window:', event.Window)
        print('WindowName:', event.WindowName)
        print('Position:', event.Position)
        print('Wheel:', event.Wheel)
        print('Injected:', event.Injected)
        print('---')
        return True
    
    def OnKeyboardEvent(event):
        print("Message Name: ", 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 chr(event.Ascii) == 'q':
            ctypes.windll.user32.PostQuitMessage(0)
        return True
    
    
    print("")
    print('Python version:')                                            
    print((sys.version))
    print("")
    
    hm = pyHook.HookManager()       # create a hook manager
    
    hm.MouseAll = OnMouseEvent      # watch for all mouse events
    hm.HookMouse()                  # set the hook
    
    hm.KeyDown = OnKeyboardEvent    # watch for "OnKeyboardEvent"
    hm.HookKeyboard()               # set the hook
    
    pythoncom.PumpMessages()
    
    
    # if you reached this point you have terminated the program correctly!
    # flush and close any open files etc.
    
    hm.UnhookMouse()
    hm.UnhookKeyboard()
    
    print("")
    print("The end of Mouse and KBD test!")
    print("")