如何使用pywin32获取Windows计划任务创建的运行进程的PID
解决方法
根本原因
你通过GetTask获取到的是IRegisteredTask接口对象,仅包含任务的静态注册信息,不包含运行时数据。EnginePID属性属于IRunningTask接口,需要从系统的运行中任务集合中查询获取。
实现步骤
步骤1:获取运行中的任务实例
先确认目标任务处于运行状态,再从运行任务集合中匹配到对应实例:
import win32com.client # 初始化任务调度服务 scheduler = win32com.client.Dispatch('Schedule.Service') scheduler.Connect() folder = scheduler.GetFolder('\\') # 替换为你的任务名称 task_name = "Name of created task" registered_task = folder.GetTask(task_name) # 任务状态为4时代表正在运行(TASK_STATE_RUNNING) if registered_task.State == 4: # 获取所有运行中的任务,参数0代表返回所有可见运行任务 running_tasks = scheduler.GetRunningTasks(0) target_running_task = None for rt in running_tasks: # 用任务路径匹配避免不同文件夹下重名任务冲突 if rt.Path == registered_task.Path: target_running_task = rt break if target_running_task: # 获取任务引擎PID engine_pid = target_running_task.EnginePID print(f"任务引擎进程PID:{engine_pid}")
步骤2:获取任务启动的业务进程PID
上面拿到的engine_pid是任务调度引擎进程(通常是taskeng.exe)的PID,你要获取的calc.exe等业务进程是该引擎的子进程,可通过psutil遍历进程树获取:
import psutil def get_child_pids(parent_pid): child_pids = [] try: parent = psutil.Process(parent_pid) children = parent.children(recursive=True) for child in children: child_pids.append((child.pid, child.name())) except psutil.NoSuchProcess: pass return child_pids # 接上面的代码,传入engine_pid business_processes = get_child_pids(engine_pid) for pid, name in business_processes: print(f"任务启动的进程:{name},PID:{pid}")
注意事项
- 访问部分系统级任务的运行信息需要管理员权限,否则可能无法匹配到运行中的任务实例
- 若任务配置了允许多实例并行运行,运行集合中会返回多个匹配的
IRunningTask对象,可根据启动时间等属性进一步筛选 psutil为第三方库,可通过pip install psutil安装使用
内容的提问来源于stack exchange,提问作者ss7
相关产品推荐
相关产品推荐

