I have a main python script that generates a GUI, and through that GUI I want the user to be able to create, amend, and delete schedules managed by the windows task scheduler.
-
Is using either WMI or schtasks.exe an option ? – FredP Oct 02 '14 at 12:43
-
Ahem... quick google results : http://blog.ziade.org/2007/11/01/scheduling-tasks-in-windows-with-pywin32/ http://sourceforge.net/projects/pytaskscheduler/ Have a nice day :-) – FredP Oct 02 '14 at 13:01
-
This looks like it was written for Python 2.3, so not exactly what I was looking for. Will see if I can scavenge from it though. – I_do_python Oct 02 '14 at 13:48
-
1With `subprocess` you could do: http://stackoverflow.com/a/2725908/660921 – Martin Tournoij Oct 02 '14 at 14:02
-
1@FredP, your solution is incompatible with 3.x. – I_do_python Oct 02 '14 at 14:05
4 Answers
This code creates a task which will run in 5 minutes (uses pywin32):
import datetime
import win32com.client
scheduler = win32com.client.Dispatch('Schedule.Service')
scheduler.Connect()
root_folder = scheduler.GetFolder('\\')
task_def = scheduler.NewTask(0)
# Create trigger
start_time = datetime.datetime.now() + datetime.timedelta(minutes=5)
TASK_TRIGGER_TIME = 1
trigger = task_def.Triggers.Create(TASK_TRIGGER_TIME)
trigger.StartBoundary = start_time.isoformat()
# Create action
TASK_ACTION_EXEC = 0
action = task_def.Actions.Create(TASK_ACTION_EXEC)
action.ID = 'DO NOTHING'
action.Path = 'cmd.exe'
action.Arguments = '/c "exit"'
# Set parameters
task_def.RegistrationInfo.Description = 'Test Task'
task_def.Settings.Enabled = True
task_def.Settings.StopIfGoingOnBatteries = False
# Register task
# If task already exists, it will be updated
TASK_CREATE_OR_UPDATE = 6
TASK_LOGON_NONE = 0
root_folder.RegisterTaskDefinition(
'Test Task', # Task name
task_def,
TASK_CREATE_OR_UPDATE,
'', # No user
'', # No password
TASK_LOGON_NONE)
More info on tasks and their properties here: https://learn.microsoft.com/en-us/windows/desktop/taskschd/task-scheduler-objects
- 2,400
- 24
- 23
Just to round out the option list here... How about just calling the windows command line?
import os
os.system(r'SchTasks /Create /SC DAILY /TN "My Task" /TR "C:mytask.bat" /ST 09:00')
You can launch any executable, batch file, or even another python script - assuming the system is set to execute python...
schtasks has a rich list of options and capabilities...https://learn.microsoft.com/en-us/windows/win32/taskschd/schtasks
- 767
- 7
- 14
- 163
- 3
- 7
PyWin32 provides an interface to the Task Scheduler in win32com.taskscheduler. You can see an example of it's use here:
Also @FredP linked to a good example that's much simpler:
There is also an interesting tidbit in the wmi module's cookbook about scheduling a job, although it doesn't appear to use the Task Scheduler:
- 2,266
- 3
- 23
- 36
- 32,629
- 8
- 45
- 88
-
Warning: Do not use the WMI method. The service which it depends on seems to be deprecated and not enabled by default (Though you can enable it via registry) since Windows 8: https://learn.microsoft.com/en-us/windows/win32/cimwin32prov/win32-scheduledjob – xendi Sep 12 '20 at 22:43
I also needed a way to use Python to schedule a task in Windows 10. I discovered something simpler, using only subprocess and PowerShell's Scheduled Tasks cmdlets, which is more powerful as it gives you finer control over the task to schedule.
And there's no need for a third-party module for this one.
import subprocess
# Use triple quotes string literal to span PowerShell command multiline
STR_CMD = """
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "C:\\path\\to\\file.ps1"
$description = "Using PowerShell's Scheduled Tasks in Python"
$settings = New-ScheduledTaskSettingsSet -DeleteExpiredTaskAfter (New-TimeSpan -Seconds 2)
$taskName = "Test Script"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddSeconds(10)
$trigger.EndBoundary = (Get-Date).AddSeconds(30).ToString("s")
Register-ScheduledTask -TaskName $taskName -Description $description -Action $action -Settings $settings -Trigger $trigger | Out-Null
"""
# Use a list to make it easier to pass argument to subprocess
listProcess = [
"powershell.exe",
"-NoExit",
"-NoProfile",
"-Command",
STR_CMD
]
# Enjoy the magic
subprocess.run(listProcess, check=True)
- 779
- 8
- 16