SendKey via AutoIT Interface

As AutoIT has been specifically created to deeply interact with Windows, I would recommend considering the interface to AutoIT whenever sphisticated control of Windows internals is required. Example: Sending keystrokes.

AutoIT can do that in an exhaustive way, and the interface between Python and AutoIT is VERY simple and elegant.
I cannot think of any keystroke, that cannot be sent with AutoIT.

See example below.

In addition, AutoIT is free and of relatively small size (18 MB).

from win32com.client import Dispatch
au = Dispatch("AutoItX3.Control")   # Access to AutoIT

...

# this sends "right, right, shift+right"
au.Send("{RIGHT}{RIGHT}+{RIGHT}")
txta = str.format("+{0}{1}{2}","{DOWN ",number,"}")
# this sends "shift+down" a 'number' of times
au.Send(txta)

Events in Autodesk Inventor

How to listen and respond to Inventor events in Python using win32com (from http://wikihelp.autodesk.com/Inventor/enu/Community/Third_Party_Tools/the_python_page/Listening_to_Events). This example assumes you have succefully been able to connect to Inventor’s COM object If you have not, please do that first.

# used to listen to the application events and also the events for a custom button
import ctypes
import win32com.client
from win32com.client.gencache import EnsureDispatch
import pythoncom

class Events():
    def __init__(self, oApp):
        global Application
        Application = oApp
   
    #Application Events
    class IVEvent():      
        def OnQuit(self, BeforeOrAfter, Context, HandlingCode):
            print("Quiting...")
            ctypes.windll.user32.PostQuitMessage(0)
            Application.Quit()
     
    #Custom Button Events      
    class BEvent():
        def OnExecute(self, Context):
            print "Dxf Button Clicked"

class DoylePlugin():    
    oApp=EnsureDispatch("Inventor.Application")
    oApp.Visible=True
      
    DxfButton=oApp.CommandManager.ControlDefinitions.AddButtonDefinition("Dxf Update", "dxf", 4)
    DxfButton.AutoAddToGUI()
    
    Events = Events(oApp)        
    AppEvents=win32com.client.DispatchWithEvents(oApp.ApplicationEvents, Events.IVEvent)
    DxfEvents=win32com.client.DispatchWithEvents(DxfButton, Events.BEvent)
    
    pythoncom.PumpMessages()

Simple VBA like MessageBox in Python

Some days ago I found a very easy pythonic way to show a VBA-like MessageBox. It was created with only one line of cpython code.

The code is very very easy. Simply change the last integer parameter to change the style of the message box.

import ctypes

msgbox = ctypes.windll.user32.MessageBoxA
ret = msgbox(None, 'Press OK to end the demo.', 'Deviare Python Demo', 0)
print ret

Find selected files in Windows Explorer

I searched a long time for this and also Google could not give me an answer to the following question. How can I detect the selected files in a Windows Explorer window? I found following by trial and error…

import win32com.client
# look in the makepy output for IE for the 'CLSIDToClassMap'
# dictionary, and find the entry for 'ShellWindows'
clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'
ShellWindows=win32com.client.Dispatch(clsid)

# a busy state can be detected:
# while ShellWindows[0].Busy == False:
# go in for-loop here

for i in range(ShellWindows.Count):
    print ShellWindows[i].LocationURL
    for j in range(ShellWindows[i].Document.SelectedItems().Count):
        print '  ', ShellWindows[i].Document.SelectedItems().Item(j).Path

# Be careful: Internet Explorer uses also the same CLSID. You should implement a detection!

PathWatcher.py keeps an eye on any changes in any directory

This little script runs only on windows and watches at low level into a givven directory. If any changes occur, it will immidiatly show you what has changed. I use it regularly to watch into a directory (works also with UNC pathes and samba) and follow, which files were modified. It watches into the complete directory tree with sub directories. Very simple, use it like this:

python.exe c:\temp\PathWatcher.py \\SRVXY\released_docs
import os, sys

import win32file
import win32con

ACTIONS = {
  1 : "Created",
  2 : "Deleted",
  3 : "Updated",
  4 : "Renamed from something",
  5 : "Renamed to something"
}

FILE_LIST_DIRECTORY = 0x0001

path_to_watch = sys.argv[1]
print 'Watching changes in', path_to_watch
hDir = win32file.CreateFile (
  path_to_watch,
  FILE_LIST_DIRECTORY,
  win32con.FILE_SHARE_READ | win32con.FILE_SHARE_WRITE,
  None,
  win32con.OPEN_EXISTING,
  win32con.FILE_FLAG_BACKUP_SEMANTICS,
  None
)
while 1:

  results = win32file.ReadDirectoryChangesW (
    hDir,
    1024,
    True,
    win32con.FILE_NOTIFY_CHANGE_FILE_NAME |
     win32con.FILE_NOTIFY_CHANGE_DIR_NAME |
     win32con.FILE_NOTIFY_CHANGE_ATTRIBUTES |
     win32con.FILE_NOTIFY_CHANGE_SIZE |
     win32con.FILE_NOTIFY_CHANGE_LAST_WRITE |
     win32con.FILE_NOTIFY_CHANGE_SECURITY,
    None,
    None
  )
  for action, file in results:
    full_filename = os.path.join (path_to_watch, file)
    print full_filename, ACTIONS.get (action, "Unknown")

Delete old mails from Outlooks deleted items folder

The following script deletes all mails older than 30 days from Outlooks Deleted Items Folder:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os, sys
import win32com.client
from datetime import datetime
from datetime import timedelta
import pywintypes

# Microsoft Outlook Constants
# http://msdn.microsoft.com/en-us/library/aa219371(office.11).aspx
olFolderDeletedItems=3
olFolderSentMail=5
# or you can use the following command to generate
# c:\python26\python.exe c:\Python26\lib\site-packages\win32com\client\makepy.py -d
# After generated, you can use win32com.client.constants.olFolderSentMail

# http://code.activestate.com/recipes/496683-converting-ole-datetime-values-into-python-datetim/
OLE_TIME_ZERO = datetime(1899, 12, 30, 0, 0, 0)
def ole2datetime(oledt):
    return OLE_TIME_ZERO + timedelta(days=float(oledt))

if __name__ == '__main__':
    app = win32com.client.Dispatch( "Outlook.Application" )
    ns = app.GetNamespace( "MAPI" )
    folders = [
        #ns.GetDefaultFolder(olFolderSentMail),
        ns.GetDefaultFolder(olFolderDeletedItems)
    ]
    for folder in folders:
        print( "Processing %s" % folder.Name )

        past30days=datetime.now()-timedelta(days=30)
        mark2delete=[]
        #If you use makepy.py, you have to use the following codes instead of "for item in folder.Items"
        #for i in range(1,folder.Items.Count+1):
        #    item = folder.Items[i]
        for item in folder.Items:
            if ole2datetime(item.LastModificationTime)0:
            for item in mark2delete:
                print( "Removing %s" % item.Subject )
                item.Delete()
        else:
            print("No matched mails.")

How to automate CATIA V6 with Python on Windows

CATIA V6 can be automated in the same way like CATIA V5. You need either the comtypes module or the Pywin32 module. The next two examples show two simple programming examples by using Pywin32, which is included in the ActivePython Distribution. If you want to use another Python Distribution, you have to install this module manually.

When you run the following two scripts, CATIA V6 should be installed and already be running.

The first example prints the names (PLMExternalID) of all selected entries in a query list of the advanced search (Silver Layer):

import win32com.client

catiaObj=win32com.client.GetActiveObject('CATIA.Application')
for i in range(catiaObj.ActiveEditor.Selection.Count):
    print 'Selected Item %s: %s'%(i, catiaObj.ActiveEditor.Selection.Item(i + 1).Value.Name)

The next example throws a query (Weld0815*) to the VPM database, gets all relevant products and places all of them on a turntable view of the Silver Layer. This is very useful, if you want to compare different Products an one turntable view.

import win32com.client

# Search for every Product with name Weld0815*
catiaObj=win32com.client.GetActiveObject('CATIA.Application')
oSearchService = catiaObj.GetSessionService("PLMSearch")
oPLMSearches = oSearchService.Searches
oPLMSearch = oPLMSearches.Add()
oPLMSearch.Type = "PLMProductDS"
oPLMSearch.AddAttributeCriteria("PLM_ExternalID",  "Weld0815*")
oPLMSearch.search()

# Iterate over all found objects and put them into the turntable view
o3DShapeAsPLMEntities = oPLMSearch.EditedContent
print 'Found %s entries.'%o3DShapeAsPLMEntities.Count
for foundobj in o3DShapeAsPLMEntities:
    print 'Putting %s onto the table'%foundobj.Name
    oSelection = catiaObj.ActiveEditor.Selection
    oSelection.Add(foundobj)
    catiaObj.StartCommand("Turntable")

Clear one contact history in Skype

This simple script enables you to delete one contact history from your Skype local database.

Let’s say your contact display name in Skype is ‘Roger G’.

I’m using vacuum statement to compact database, I believe it’s more secure that way.

import sqlite3

conn = sqlite3.connect('C:\\Users\\your_user_name\\AppData\\Roaming\\Skype\\skype_account_name\\main.db')
c = conn.cursor()

c.execute("SELECT DISTINCT convo_id FROM Messages WHERE from_dispname = 'Roger G';")
result = c.fetchone()
if result is not None:
    convo_id = int(result[0])
    c.execute("DELETE FROM Messages where convo_id = {}".format(convo_id))
    deleted = int(conn.total_changes)
    print("Deleted: {}".format(deleted))
    c.execute("VACUUM;")
    print("Vacuumed...")
conn.close()
print("Finished")

Show the path of all Explorer Windows

This piece of Python code shows the current path of all opened Explorer Windows

from win32com.client.gencache import EnsureDispatch

for w in EnsureDispatch("Shell.Application").Windows():
    print w.LocationName + "=" + w.LocationURL

I wanted to write a code, which can make use of a handler to a Windows Explorer Window, so that I can show a small Tooltip or anything else dynamically belonging to a selected Path of the User. But I think this is the better way. Hope someone alse can use this…

Also the output shows a path of Internet Explorer and Microsoft Outlook:

>>> 
outlook:Posteingang outlook:Posteingang
Tools file:///C:/Users/me/Tools
Kurz notiert http://www.goermezer.de/content/blogsection/2/633
>>>

May be we would need a detection here for Outlook or Internet Explorer.