Fetchez le Python

Technical blog on the Python programming language, in a pure Frenglish style

Scheduling tasks in Windows with PyWin32

I am posting this small entry because it took me quite a time to compute all informations to programmatically add tasks in Windows using pywin32, so this post should be an helpfull example.

The process to schedule a task is as follows:

  • create an instance of the COM TaskScheduler interface
  • adding a task within the task scheduler
  • adding a trigger within the task

Here’s how it can look in Python, to create daily tasks:

import pythoncom, win32api
import time
from win32com.taskscheduler import taskscheduler

def create_daily_task(name, cmd, hour=None, minute=None):
    """creates a daily task"""
    cmd = cmd.split()
    ts = pythoncom.CoCreateInstance(taskscheduler.CLSID_CTaskScheduler,None,
                                    pythoncom.CLSCTX_INPROC_SERVER,
                                    taskscheduler.IID_ITaskScheduler)

    if '%s.job' % name not in ts.Enum():
        task = ts.NewWorkItem(name)

        task.SetApplicationName(cmd[0])
        task.SetParameters(' '.join(cmd[1:]))
        task.SetPriority(taskscheduler.REALTIME_PRIORITY_CLASS)
        task.SetFlags(taskscheduler.TASK_FLAG_RUN_ONLY_IF_LOGGED_ON)
        task.SetAccountInformation('', None)
        ts.AddWorkItem(name, task)
        run_time = time.localtime(time.time() + 300)
        tr_ind, tr = task.CreateTrigger()
        tt = tr.GetTrigger()
        tt.Flags = 0
        tt.BeginYear = int(time.strftime('%Y', run_time))
        tt.BeginMonth = int(time.strftime('%m', run_time))
        tt.BeginDay = int(time.strftime('%d', run_time))
        if minute is None:
            tt.StartMinute = int(time.strftime('%M', run_time))
        else:
            tt.StartMinute = minute
        if hour is None:
            tt.StartHour = int(time.strftime('%H', run_time))
        else:
            tt.StartHour = hour
        tt.TriggerType = int(taskscheduler.TASK_TIME_TRIGGER_DAILY)
        tr.SetTrigger(tt)
        pf = task.QueryInterface(pythoncom.IID_IPersistFile)
        pf.Save(None,1)
        task.Run()
    else:
        raise KeyError("%s already exists" % name)

    task = ts.Activate(name)
    exit_code, startup_error_code = task.GetExitCode()
    return win32api.FormatMessage(startup_error_code)

You can see an example of usage here, in the iw.win32 package we have started to build, to gather all win32 specific Python things.

Filed under: plone, python, windows, zope ,

5 Responses

  1. Tim Golden says:

    Aargh! By a feat of supremely bad timing on my part, I have a half-completed wrapper around this very functionality which I have not quite got around to publishing. I made the mistake I always do, and tried to make a finished product rather than just getting some functionality out there!

    I agree, it is a bit painful to get round. If you’re interested in comparing notes, have a look at:

    http://timgolden.me.uk/scheduled_tasks/scheduled_tasks.py

    TJG

  2. sidnei says:

    Be careful with “taskscheduler.REALTIME_PRIORITY_CLASS”.

    If your task is very resource-intensive it might lockup your machine. We had a problem with that when using scheduled tasks and packing a ZODB.

    Contrary to other operating systems out there, seems like “REALTIME” is really “REALTIME” on Windows, and nothing else will be allowed to execute.

  3. Tarek Ziadé says:

    @Tim, Thanks, yours is way more complete ! I think i’ll try to define a common API that can be used no matter what the OS is.

    @Sidnei, ok, good to know, thanks !

  4. david jensen says:

    I just started working with the samples using py2.5.2 on Vista Ultimate.
    To create a task, at ts.AddWorkItem(name, task), it says access is denied. In an administrator account, Vista is very uncomfortable to work because it is always asking for permission. I tried to turn this off, but could not find a way. I will try this on XP, but I think the problem may be Vista security.

  5. Tarek Ziadé says:

    @david jensen: that’s weird.. do you get like a popup ? I don’t know at all how how security works under Windows , so if you get it through please let us know here !

Leave a Reply