Skip to main content.
December 22nd, 2006

How to Send F6 with Only a Number Pad (Stupid Python Tricks)

This little script will detect when you hit certain number pad numbers and send the specified function keys on to Windows instead:

import win32com.client
import pythoncom
import pyHook # http://sourceforge.net/projects/uncassist

def translate_keystrokes(event):
    if event.Key=='Numpad6': #Next in Screen Saver
        print 'You hit numpad 6!'
        shell.SendKeys("{F7}")
        return False #blocks keystroke
    elif event.Key=='Numpad4': #Previous in Screen Saver
        print 'You hit numpad 4!'
        shell.SendKeys("{F6}")
        return False #blocks keystroke
    else:
        return True #Key stroke continues to Windows apps  

#object to let us send keystrokes
shell = win32com.client.Dispatch("WScript.Shell")
# create a hook manager
hm = pyHook.HookManager()
# watch for all keyboard events
hm.KeyDown = translate_keystrokes
# set the hook
hm.HookKeyboard()
# wait forever
pythoncom.PumpMessages()

Why on earth would I want to do this?
Well, this lets me control a screensaver application with a $10 number pad so that the laptop controlling the display can be tucked away out of site. The alternative was to buy this $80 programmable keypad. (If you hadn’t guessed, the screen saver inflexibly requires F6 to move to the next page.)

To make this little script I followed the pyHook examples here. And figured out how to send keystrokes here.

Finally this page gives you a run down on what WScript.Shell does. And this project looks like another promising alternative for sending keystrokes.

Posted by Greg Pinero (Primary Searcher) as GUI Automation, win32, Python at 6:34 PM MST

2 Comments »

August 2nd, 2006

Why Killing Processes may be Hurting You and What to Do About it

First the Background:
A while back I wrote an insane program to automate Omnipage 14 (an OCR program) mostly via GUI automation. The urge to do this was caused by Omnipage not handling more than 300 files on its own before dying, and the lack of a better solution in the market place.
So Omnipage was very tempermental and quit often for all kinds of unexplained reasons. So my solution was to feed Omnipage 3 files at once and when it finished OCR’ing the 3 files kill all of its processes. Then give it 3 new files and relaunch it and so on.

Once I had completed the programming I set it off on it’s own to work on a network drive full of ~30,000 files needing to be OCR’d.

1 month goes by …

I come back to check on it and here is what I see on the screen!
System Tray Chaos
Apparently killing the processes didn’t allow some Omnipage process to clear its system tray icon. So as the headline promised here is at least one way that killing a process is harmful (and humorous). I’m sure there are plenty of more serious reasons though. (Yes, moving the mouse over these icons caused them to dissapear, so I spent a challenging 30 minutes randomly moving my mouse around the system tray and exterminating these things … )

A Better Option Than Killing
After that experience, here is the method I switched to. After Omnipage finishes its 3 files, I kindly request that it close itself using Python’s Win32 extensions. Here is the code (mostly copied from their win32 examples):

import sys
import win32process, win32api, win32pdhutil, win32con, win32security
import win32event, msvcrt, win32gui

def get_all_windows():
    """Returns dict with window desc and hwnd"""
    def _MyCallback( hwnd, extra ):
        """Helper function"""
        hwnds, classes = extra
        hwnds.append(hwnd)
        classn = win32gui.GetClassName(hwnd)
        if not classn in classes:
            classes[classn] = []
        classes[classn].append( hwnd )
    windows = []
    classes = {}
    win32gui.EnumWindows(_MyCallback, (windows, classes))
    return classes

def request_windows_to_close(list_window_descs_to_close):
    """Send me a list of stuff to close such as:stuff_to_close=['OP15_OmniPage_Agent_Class']
    run get_all_windows() to see what's available"""
    classes=get_all_windows()
    for windesc_to_close in list_window_descs_to_close:
        if windesc_to_close in classes:
            for hwnd in classes[windesc_to_close]:
                win32gui.PostMessage( hwnd, win32con.WM_CLOSE, 0, 0 )
                print 'requested closure with', windesc_to_close
        else:
            print 'Did not find a window desc. as',windesc_to_close

Life is good now I think :-)

Points of discussion:

  1. Did I miss an OCR product that I can just give it a directory with up to 60K files and have it OCR them into PDF’s?
  2. Is there a programmatic way to ask Windows to refresh the system tray (Don’t say moving the mouse programmatically over the system, that’s cheating.)
  3. I considered using the Omnipage SDK instead of GUI automation but it looked too expensive and hard to learn. Has anyone had experience with that method?

Tags: , , , , , , , , , , , , , ,

Posted by Greg Pinero (Primary Searcher) as GUI Automation, win32, Python, Automation at 12:10 PM MST

6 Comments »

January 5th, 2006

Stop Locking My Computer After 15 Minutes Of Inactivity! (For Windows Server 2003 at least)


This will make your computer (at least one running Windows Server 2003) never lock after inactivity and not require ctl-alt-del to login in. It may be similar for Windows XP too.

Here’s the answer:

  1. Goto Start>Run and type gpedit.msc
  2. Once it comes up go to computer configuration go to Windows>Settings>local policies>security options
    (For Windows XP you’d go to: Windows Settings>Security Settings>Local Policies>Security Options)
  3. From there you will see the require Ctl-Alt-Del setting. Disable it. (I’m not sure if you need to do this and this isn’t shown here in Windows XP.)
  4. Next find the one that says “Amount of idle time required before suspending session” and change it to its maximum value 99999.

I found part of this answer here.

It was quite hard to to locate this gem of information on the web but here are all of the searches I tried:

  1. “this computer is in use and has been locked” #The message I want to not see
  2. disable “this computer is in use and has been locked”
  3. “Server 2003″ lock after time
  4. “Server 2003″ auto logoff after set time
  5. “Server 2003″ locked

Posted by Greg Pinero (Primary Searcher) as VNC, GUI Automation, win32 at 6:20 PM MST

2 Comments »

December 22nd, 2005

Fixing - AutoIt stops running/hangs under terminal services


I wrote a nice AutoIt script to automate Omnipage14 because it offered no way whatsoever for a Python script to control it. Anyway everything worked except that I was running it under terminal services on another computer and whenever the terminal services window lost focus or I logged off, AutoIt just stopped running. So I spent quite a while searching and found these solutions:

The short answer is:
Give up! .. don’t run it under terminal services, try VNC instead.

The long answer is:
I searched for too many terms to even recall. I came across a lot of websites and a lot of advice for this problem. The basic problem is that when you’re not actively using terminal services, the desktop and everything GUI goes away somehow. That’s why Autoit stopped working. I tried setting up the AutoIt script to run as a service but nothing happened when I launched the service and it seemed like an overly-complex solution to research any further. The second solution I had come across (using VNC) seemed like a reasonable idea so I went that route and everything is now working fine.

Here are the discussions I found on this issue:
http://www.autoitscript.com/forum/lofiversion/index.php?t4026.html
http://tinyurl.com/8yh3w
http://tinyurl.com/7wmvy

Posted by Greg Pinero (Primary Searcher) as VNC, GUI Automation at 3:52 PM MST

Comments Off