Events in Microsoft Project

I found this very interesting Python script, which showes how to use Events in Microsoft Project with Python for Windows. Simply dispatch with an eventmanager class:

import win32com.client
import pythoncom

defaultNamedNotOptArg = pythoncom.Empty

class EventManager(object):
    def OnProjectBeforeSave(self, pj=defaultNamedNotOptArg, SaveAsUi=defaultNamedNotOptArg, Cancel=defaultNamedNotOptArg):
        print 'Project saved'
        pass
    def OnProjectBeforeClose(self, pj=defaultNamedNotOptArg, Cancel=defaultNamedNotOptArg):
        print 'Project closed'
        pass
    def OnProjectTaskNew(self, pj=defaultNamedNotOptArg, ID=defaultNamedNotOptArg):
        print 'Task created'
        pass
    def OnProjectBeforeTaskChange(self, tsk=defaultNamedNotOptArg, Field=defaultNamedNotOptArg, NewVal=defaultNamedNotOptArg, Cancel=defaultNamedNotOptArg):
        print 'Field %s of Task %s changed to %s'%(Field, tsk, NewVal)
        pass
    def OnProjectBeforeTaskDelete(self, tsk=defaultNamedNotOptArg, Cancel=defaultNamedNotOptArg):
        print 'Task %s deleted'%tsk
        pass

app = win32com.client.DispatchWithEvents('MSProject.Application', EventManager)
doc = app.ActiveProject
app.Visible=1

Remote monitoring Windows

This script requests following informations remotely from a Windows machine:

  • Uptime
  • CPU Utilization
  • Available Memory
  • Memory Used
  • Ping

Attention: This script needs the WMI module from Tim Golden.

import re
import wmi
from subprocess import Popen, PIPE
# this script comes from http://coreygoldberg.blogspot.com/2008/12/python-monitor-windows-remotely-with.html


def get_uptime(computer, user, password):
    c = wmi.WMI(computer=computer, user=user, password=password, find_classes=False)
    secs_up = int([uptime.SystemUpTime for uptime in c.Win32_PerfFormattedData_PerfOS_System()][0])
    hours_up = secs_up / 3600
    return hours_up


def get_cpu(computer, user, password):
    c = wmi.WMI(computer=computer, user=user, password=password, find_classes=False)
    utilizations = [cpu.LoadPercentage for cpu in c.Win32_Processor()]
    utilization = int(sum(utilizations) / len(utilizations))  # avg all cores/processors
    return utilization

    
def get_mem_mbytes(computer, user, password):
    c = wmi.WMI(computer=computer, user=user, password=password, find_classes=False)
    available_mbytes = int([mem.AvailableMBytes for mem in c.Win32_PerfFormattedData_PerfOS_Memory()][0])
    return available_mbytes


def get_mem_pct(computer, user, password):
    c = wmi.WMI(computer=computer, user=user, password=password, find_classes=False)
    pct_in_use = int([mem.PercentCommittedBytesInUse for mem in c.Win32_PerfFormattedData_PerfOS_Memory()][0])
    return pct_in_use
    
    
def ping(host_name):
    p = Popen('ping -n 1 ' + host_name, stdout=PIPE)
    m = re.search('Average = (.*)ms', p.stdout.read())
    if m:
        return True
    else:
        raise Exception 

Form extractor from word to Excel

Konrads Smelkovs had a bunch of filled out word documents with word forms in them and neded them in Excel. Initially he tried CSV but it didn’t play nice with encodings. So he decided to write directly to XLS:

"""
Copyright 2009 Konrads Smelkovs 
UTF8Recorder and UnicodeWriter come from python docs
"""

import sys,os,csv
import win32com.client
import pywintypes


class ExcelWriter(object):
    def __init__(self,excelfile):
        self.excelapp=win32com.client.DispatchEx('Excel.Application')
        self.excelapp.Visible=0
        self.excelapp.Application.AskToUpdateLinks=0
        self.workbook=self.excelapp.Workbooks.Add()
        os.unlink(excelfile) #TODO: remove for release
        self.workbook.SaveAs(excelfile)
        # Only worksheet 1 is used.
        self.worksheet=self.workbook.Worksheets.Item(1)
        self.currentrow=1

    def _getrow(self,row):
        """Convert integer row index to Alphabetical:
        1 -> A
        2 -> B
        ...
        """
        if row<27:
            return chr(ord('A')-1 + row)
        else:
            first=row / 26
            return chr(ord('A')-1 + first) +  chr(ord('A')-1 + row % 26)
        
    def __del__(self):
        self.workbook.Save()
        self.workbook.Close()
        self.excelapp.Quit()

    def writerow(self,data):
        for col in xrange(1,len(data)+1):
            range=self._getrow(col)+str(self.currentrow)
            print >>sys.stderr,"Range: %s"  % range
            cell=self.worksheet.Range(range)
            cell.Value=data[col-1]
        self.currentrow+=1
        
def main():
 if len(sys.argv)<3:
    print "Usage: %s  " % sys.argv[0]
    print "Where  - directory containing word docs with forms"
    print "and  - file where to put results"
    sys.exit(-1)
 directory=os.path.abspath(sys.argv[1])
 wordapp = win32com.client.Dispatch("Word.Application")
 wordapp.Visible=0 # Hide word app
 results=[]
 for docfile in os.listdir(directory):
     thisdocresults=[]
     if docfile.endswith(".doc") or docfile.endswith(".docx"):
         print >> sys.stderr, "Processing %s" % docfile
         worddoc=wordapp.Documents.Open(os.path.join(directory,docfile))
         for i in range(1,worddoc.FormFields.Count+1):
            try:
                form=worddoc.FormFields.Item(i)
                name=form.Name
                value=form.Result
                thisdocresults.append((name,value))
                try:
                    print >>sys.stderr, "%s: %s" % (name,value)
                except UnicodeEncodeError,e:
                    print >>sys.stderr, "Error decoding charset,%s" % e
            except pywintypes.com_error,e:
                print >>sys.stderr, "Exception: %s" % str(e)
         results.append(thisdocresults)
         worddoc.Close()
 wordapp.Quit()
 writer=ExcelWriter(os.path.abspath(sys.argv[2]))
 print >>sys.stderr,"Writing to Excel"
 for docres in results:
     data=[]
     for (n,v) in docres:
         data.append(v)
     writer.writerow(data)
 
if __name__=="__main__":
    main()

Change Desktop color with ctypes

from ctypes.wintypes import windll, c_int, byref, RGB
COLOR_BACKGROUND = 1 # from winuser.h or win32con
SetSysColors = windll.user32.SetSysColors
which_color = RGB(255,0,0) # red
SetSysColors(1, byref(c_int(COLOR_BACKGROUND)), byref(c_int(which_color)))

Remote calls to a windows maschine

Here http://coreygoldberg.blogspot.com is another script to remotely get

  • Uptime
  • CPU Utilization
  • Available Memory
  • Memory Used
  • Ping

with Python and the wmi module. Simply drop the wmi module and the script into a directory and import it from a separate script or i.e. add a

get_cpu("maschine_name")

.

Here is the source code:

import re
import wmi
from subprocess import Popen, PIPE



def get_uptime(computer, user, password):
    c = wmi.WMI(find_classes=False, computer=computer, user=user, password=password)
    secs_up = int([uptime.SystemUpTime for uptime in c.Win32_PerfFormattedData_PerfOS_System()][0])
    hours_up = secs_up / 3600
    return hours_up


def get_cpu(computer, user, password):
    c = wmi.WMI(find_classes=False, computer=computer, user=user, password=password)
    utilizations = [cpu.LoadPercentage for cpu in c.Win32_Processor()]
    utilization = int(sum(utilizations) / len(utilizations))  # avg all cores/processors
    return utilization

    
def get_mem_mbytes(computer, user, password):
    c = wmi.WMI(find_classes=False, computer=computer, user=user, password=password)
    available_mbytes = int([mem.AvailableMBytes for mem in c.Win32_PerfFormattedData_PerfOS_Memory()][0])
    return available_mbytes


def get_mem_pct(computer, user, password):
    c = wmi.WMI(find_classes=False, computer=computer, user=user, password=password)
    pct_in_use = int([mem.PercentCommittedBytesInUse for mem in c.Win32_PerfFormattedData_PerfOS_Memory()][0])
    return pct_in_use
    
    
def ping(host_name):
    p = Popen('ping -n 1 ' + host_name, stdout=PIPE)
    m = re.search('Average = (.*)ms', p.stdout.read())
    if m:
        return True
    else:
        raise Exception  

Export variables on win32 like in Unix

This script comes from Activestate. It exports a variable permanently on win32 – without needing to reboot the system. Note: pywin32 must be installed to run the script.

Use it like this:

import win32export
win32export.export("fooname" , "foovalue")

And here comes the script. Save it as win32export.py and use it from other scripts or from the command line.

"""
vim: set enc=utf-8

Author :  winterTTr
Mail   :  winterTTr (at) gmail.com
Desc   :  Tools for Operation on Win32 Environment variables
Module :  win32export.py
"""

import win32gui
import win32con
import win32api

def export ( name , value , update_system = True ):
    try :
        modifyVariableInRegister( name , value )
    except:
        return False

    if update_system :
        updateSystem()

    return True

def modifyVariableInRegister( name , value ):
    key = win32api.RegOpenKey( win32con.HKEY_CURRENT_USER,"Environment",0,win32con.KEY_ALL_ACCESS)
    if not key : raise
    win32api.RegSetValueEx( key , name , 0 , win32con.REG_SZ , value )
    win32api.RegCloseKey( key )

def updateSystem():
    rc,dwReturnValue = win32gui.SendMessageTimeout( win32con.HWND_BROADCAST , win32con.WM_SETTINGCHANGE , 0 , "Environment" , win32con.SMTO_ABORTIFHUNG, 5000)

Adobe Photoshop automation

The following script adjusts the brightness and contrast of an image via COM automation of Adobe Photoshop with Python and the win32com package.

import win32com.client  
psApp = win32com.client.Dispatch("Photoshop.Application") 
psApp.Open(r"D:\temp\blah.psd")         # Opens a PSD file  
doc = psApp.Application.ActiveDocument  # Get active document object  
layer = doc.ArtLayers[0]                # Get the bottom-most layer  
layer.AdjustBrightnessContrast(20,-15)  # Bright +20, Contrast -15  
doc.Save() 

This comes from http://techarttiki.blogspot.com/2008/08/photoshop-scripting-with-python.html where you can find more excellent examples to automate Adobe Photoshop.

Alarm clock on a Windows machine

Following example comes from Activestate (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/510387) and represents an alarm clock on Windows:

try:
    import os
    import sys
    import time
    import msvcrt
    import winsound
except ImportError, error:
    sys.stdout.write('ImportError: %s' % error)
    sys.exit(1)

def main():
    try:
        arg = time.strptime(sys.argv[1], '%H:%M')
        arg_sec = (arg.tm_hour * 60 + arg.tm_min) * 60
        now = time.localtime()
        now_sec = (now.tm_hour * 60 + now.tm_min) * 60 + now.tm_sec
        alarm(arg_sec - now_sec + (86400 if arg_sec <= now_sec else 0))
    except:
        sys.stdout.write(os.path.basename(sys.argv[0]))
        sys.stdout.write(' HH:MM')

def alarm(seconds):
    time.sleep(seconds)
    while msvcrt.kbhit():
        msvcrt.getch()
    while not msvcrt.kbhit():
        winsound.Beep(440, 250)
        time.sleep(0.25)

if __name__ == '__main__':
    main()

Simple OpenOffice COM auomation example

from win32com.client.dynamic import Dispatch
objServiceManager = Dispatch('com.sun.star.ServiceManager')
Stardesktop = objServiceManager.CreateInstance('com.sun.star.frame.Desktop')
doc = Stardesktop.loadComponentfromURL('private:factory/swriter', '_blank', 0, [])
text = doc.getText()
text.setString("Hello World") 

Let merlin think (MS Agent automation)

import win32com.client
ag=win32com.client.Dispatch("Agent.Control")
ag.Connected=1
ag.Characters.Load("Merlin")
ag.Characters("Merlin").Show()
text = raw_input("please type something...")
ag.Characters("Merlin").Think(text)