Python is great for automating repetitive tasks, and Windows Task Scheduler is a powerful tool for scheduling processes. By integrating Python and the Win32COM interface, you can programmatically control Task Scheduler, enabling dynamic and customizable task scheduling. This guide walks through a real-world example of using Python to create and manage a scheduled task that zips video files older than 30 days.
Why Use Win32COM for Task Scheduler?
The Win32COM module (part of pywin32
) allows Python to interact with Windows-specific COM objects. This library can create, modify, and delete scheduled tasks directly from your scripts.
In this example, we’ll focus on the task of archiving video files. However, the principles apply to any scenario requiring scheduled execution of scripts or programs.
Setting Up the Environment
Before diving into the code, create a virtual environment to keep the project dependencies isolated.
Windows Only:
python -m venv venv
venv\Scripts\activate
pip install pywin32
This library provides the win32com.client
module, which lets Python interact with Windows Task Scheduler.
Writing the Archival Script
First, create the script zip_old_videos.py
to zip video files older than 30 days. This script operates independently of Task Scheduler but will be executed automatically through our scheduled task.
import os
import zipfile
from datetime import datetime, timedelta
VIDEOS_DIR = "C:\\Path\\To\\videos"
ARCHIVE_DIR = "C:\\Path\\To\\archived_videos"
RETENTION_DAYS = 30
def zip_videos_older_than_30_days():
# Ensure the archive directory exists
if not os.path.exists(ARCHIVE_DIR):
os.makedirs(ARCHIVE_DIR)
cutoff_date = datetime.now() - timedelta(days=RETENTION_DAYS)
videos_by_day = {}
# Group videos by recording date
for file_name in os.listdir(VIDEOS_DIR):
file_path = os.path.join(VIDEOS_DIR, file_name)
if os.path.isfile(file_path) and file_name.endswith(".mp4"):
file_mod_time = datetime.fromtimestamp(os.path.getmtime(file_path))
if file_mod_time < cutoff_date:
day_key = file_mod_time.strftime("%Y-%m-%d")
if day_key not in videos_by_day:
videos_by_day[day_key] = []
videos_by_day[day_key].append(file_path)
# Zip each group of videos
for day, files in videos_by_day.items():
zip_file_name = os.path.join(ARCHIVE_DIR, f"{day}.zip")
with zipfile.ZipFile(zip_file_name, 'w') as zipf:
for file_path in files:
zipf.write(file_path, arcname=os.path.basename(file_path))
print(f"Archived {len(files)} videos from {day} into {zip_file_name}")
if __name__ == "__main__":
zip_videos_older_than_30_days()
This script:
- Identifies
.mp4
files older than 30 days. - Groups them by the day they were modified.
- Compresses each day’s videos into a ZIP archive.
Automating with Win32COM and Task Scheduler
The real power comes from automating the execution of this script. By leveraging Win32COM, we’ll create a scheduled task that runs the archival script every day at 2:00 AM.
Creating the Task Scheduler Script
Save the following script as schedule_zip_task.py
:
import os
import win32com.client
TASK_NAME = "ZipOldVideos"
SCRIPT_PATH = os.path.abspath("zip_old_videos.py")
TRIGGER_TIME = "02:00"
def schedule_task():
# Connect to Task Scheduler
scheduler = win32com.client.Dispatch("Schedule.Service")
scheduler.Connect()
# Get the root folder of Task Scheduler
root_folder = scheduler.GetFolder("\\")
# Create a new task
task_definition = scheduler.NewTask(0)
# Set task metadata
task_definition.RegistrationInfo.Description = "Zips videos older than 30 days into daily archives"
task_definition.RegistrationInfo.Author = "Automation Script"
# Create a daily trigger
trigger = task_definition.Triggers.Create(2) # 2 = Daily Trigger
trigger.StartBoundary = f"2024-12-03T{TRIGGER_TIME}:00"
trigger.DaysInterval = 1
# Set the action to run the Python script
action = task_definition.Actions.Create(0) # 0 = Exec action
action.Path = "python"
action.Arguments = SCRIPT_PATH
# Configure task settings
settings = task_definition.Settings
settings.Enabled = True
settings.StartWhenAvailable = True
settings.Hidden = False
# Register the task
root_folder.RegisterTaskDefinition(
TASK_NAME,
task_definition,
6, # TASK_CREATE_OR_UPDATE
None, # No username (runs with the current user)
None, # No password
0 # Logon type: Interactive or Batch
)
print(f"Task '{TASK_NAME}' created successfully.")
if __name__ == "__main__":
schedule_task()
How It Works
- Task Scheduler Connection: The script connects to the Task Scheduler API using
win32com.client.Dispatch("Schedule.Service")
.
2. Task Definition: A new task is created with triggers and actions.
- Trigger: Configured to run daily at 2:00 AM.
- Action: Executes
zip_old_videos.py
using Python.
3. Task Registration: The RegisterTaskDefinition
method saves the task in Task Scheduler.
Testing and Deployment
Run the scheduling script:
python schedule_zip_task.py
- Verify the task in Task Scheduler:
- Open Task Scheduler (
Start > Task Scheduler
). - Navigate to “Task Scheduler Library” and locate the “ZipOldVideos” task.
- Wait for the next execution or manually run the task to test it.
Advantages of Using Win32COM
- Dynamic Scheduling: Tasks can be created, modified, or deleted programmatically, enabling flexible automation.
- Integration: Easily integrates with existing Python scripts or workflows.
- Efficiency: No manual intervention is needed once the task is scheduled.
Here’s a Python script using the win32com.client
module to delete or remove a scheduled task from Task Scheduler. The script allows you to specify the task name to remove.
import win32com.client
def delete_scheduled_task(task_name):
try:
# Connect to Task Scheduler
scheduler = win32com.client.Dispatch("Schedule.Service")
scheduler.Connect()
# Get the root folder
root_folder = scheduler.GetFolder("\\")
# Delete the task
root_folder.DeleteTask(task_name, 0) # 0 means no special flags
print(f"Task '{task_name}' deleted successfully.")
except Exception as e:
print(f"Error deleting task '{task_name}': {e}")
if __name__ == "__main__":
# Specify the name of the task to delete
task_name = "ZipOldVideos" # Replace with your task name
delete_scheduled_task(task_name)
How It Works:
- Connect to Task Scheduler: The script initializes the
Schedule.Service
COM object and connects to Task Scheduler. - Access the Root Folder: The root folder is the default container for tasks unless a specific folder is used.
- Delete the Task: The
DeleteTask
method removes the specified task by name
Thank you for reading this article. I hope you found it helpful and informative. If you have any questions, or if you would like to suggest new Python code examples or topics for future tutorials, please feel free to reach out. Your feedback and suggestions are always welcome!
Happy coding!
C. C. Python Programming
You can also find this article at Medium.com