ScheduleTaskManager 是 ZerOS 内核的计划任务管理器,负责管理系统级的计划任务。支持在特定情况(系统启动完成、系统关闭前等)或特定时间(或时间区间)运行程序、命令或服务(ServerExpansion 服务及其暴露的 API,如启动/停止)。计划任务数据持久化存储在 LocalSData.json 中。
program)、执行命令(command)、服务(service,即 ServerExpansion 服务的启动/停止)runInBackground: false 改为前台启动LocalSData.json,系统重启后自动恢复autoStart=true 的程序(普通用户无法手动启动这些程序)ProcessManager - 进程管理器(用于启动程序)LStorage - 本地存储(用于持久化计划任务数据)ApplicationAssetManager - 应用程序资源管理器(用于验证程序是否存在)PermissionManager - 权限管理器(用于权限验证)KernelLogger - 内核日志(用于日志记录)计划任务数据存储在 LocalSData.json 文件的 scheduleTaskManager.tasks 键中:
{
"system": {
"scheduleTaskManager.tasks": [
{
"id": "task_1234567890_abc123",
"programName": "terminal",
"triggerType": "SYSTEM_STARTUP",
"triggerConfig": {},
"enabled": true,
"createdAt": 1234567890000,
"updatedAt": 1234567890000,
"lastRunAt": 0,
"runCount": 0,
"createdBy": "myapp",
"requiresStartupPermission": false
}
]
}
}
ScheduleTaskManager.TRIGGER_TYPE = {
SYSTEM_STARTUP: 'SYSTEM_STARTUP', // 系统启动完成
SYSTEM_SHUTDOWN: 'SYSTEM_SHUTDOWN', // 系统关闭前
SPECIFIC_TIME: 'SPECIFIC_TIME', // 特定时间(如每天 09:30)
TIME_RANGE: 'TIME_RANGE', // 时间区间(如 09:00-18:00,每 30 分钟)
INTERVAL: 'INTERVAL' // 间隔时间(周期性任务,如每 60 分钟)
};
不需要额外配置,triggerConfig 可以为空对象 {}。
{
time: '09:30' // 格式:HH:mm(24小时制)
}
{
startTime: '09:00', // 开始时间(格式:HH:mm)
endTime: '18:00', // 结束时间(格式:HH:mm)
interval: 30 // 执行间隔(分钟数,至少1分钟)
}
interval 分钟执行一次{
interval: 60 // 执行间隔(分钟数,至少1分钟)
}
计划任务 API 调用需要相应的权限:
注意:
SCHEDULE_TASK_CREATE 权限SCHEDULE_TASK_STARTUP 权限(危险权限)所有计划任务功能都通过 ProcessManager.callKernelAPI 调用:
// 创建计划任务
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'terminal',
triggerType: 'SYSTEM_STARTUP',
triggerConfig: {},
enabled: true
}, false] // requiresStartupPermission = false
);
// 获取所有任务
const tasks = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.getAll',
[]
);
ScheduleTask.create(taskConfig, requiresStartupPermission)创建计划任务。
参数:
taskConfig (Object, 必需): 任务配置
taskType (string, 可选): 任务类型,'program' | 'command' | 'service',默认 'program'programName (string, 当 taskType 为 program 时必需): 程序名称runInBackground (boolean, 当 taskType 为 program 时可选): 是否以后台方式启动程序;默认 true(不显示在任务栏、多任务选择器);设为 false 时以前台方式启动command (string, 当 taskType 为 command 时必需): 要执行的命令serviceId (string, 当 taskType 为 service 时必需): 服务 ID(ServerExpansion 中的服务标识,如 notice)serviceAction (string, 当 taskType 为 service 时可选): 服务操作,'start' | 'stop',默认 'start'triggerType (string, 必需): 触发类型(SYSTEM_STARTUP、SYSTEM_SHUTDOWN、SPECIFIC_TIME、TIME_RANGE、INTERVAL)triggerConfig (Object, 必需): 触发配置(根据触发类型不同而不同)enabled (boolean, 可选): 是否启用(默认 true)requiresStartupPermission (boolean, 可选): 是否需要系统启动权限(默认 false)
true: 系统启动后的计划任务,需要 SCHEDULE_TASK_STARTUP 权限(危险权限)false: 普通计划任务,需要 SCHEDULE_TASK_CREATE 权限(特殊权限)返回值: Promise<string> - 任务ID
示例:
// 创建系统启动后的计划任务(需要危险权限)
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'filemanager',
triggerType: 'SYSTEM_STARTUP',
triggerConfig: {},
enabled: true
}, true] // requiresStartupPermission = true
);
// 创建特定时间任务(每天 09:30 运行)
const taskId2 = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'terminal',
triggerType: 'SPECIFIC_TIME',
triggerConfig: {
time: '09:30'
},
enabled: true
}, false] // requiresStartupPermission = false
);
// 创建时间区间任务(09:00-18:00,每 30 分钟运行一次)
const taskId3 = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'musicplayer',
triggerType: 'TIME_RANGE',
triggerConfig: {
startTime: '09:00',
endTime: '18:00',
interval: 30
},
enabled: true
}, false]
);
// 创建间隔任务(每 60 分钟运行一次)
const taskId4 = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'timer',
triggerType: 'INTERVAL',
triggerConfig: {
interval: 60
},
enabled: true
}, false]
);
ScheduleTask.delete(taskId)删除计划任务。
参数:
taskId (string, 必需): 任务ID返回值: Promise<boolean> - 是否成功
权限: 需要 SCHEDULE_TASK_MANAGE 权限
示例:
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.delete',
['task_1234567890_abc123']
);
ScheduleTask.update(taskId, updates)更新计划任务。
参数:
taskId (string, 必需): 任务IDupdates (Object, 必需): 更新内容
enabled (boolean, 可选): 是否启用triggerConfig (Object, 可选): 触发配置返回值: Promise<boolean> - 是否成功
权限: 需要 SCHEDULE_TASK_MANAGE 权限
示例:
// 禁用任务
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.update',
['task_1234567890_abc123', { enabled: false }]
);
// 更新触发配置
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.update',
['task_1234567890_abc123', {
triggerConfig: {
time: '10:00' // 改为 10:00 执行
}
}]
);
ScheduleTask.get(taskId)获取计划任务信息。
参数:
taskId (string, 必需): 任务ID返回值: Promise<Object|null> - 任务信息对象,如果不存在则返回 null
权限: 无需权限(读取操作)
示例:
const task = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.get',
['task_1234567890_abc123']
);
if (task) {
console.log('任务信息:', task);
console.log('程序名称:', task.programName);
console.log('触发类型:', task.triggerType);
console.log('是否启用:', task.enabled);
console.log('运行次数:', task.runCount);
}
ScheduleTask.getAll()获取所有计划任务。
参数: 无
返回值: Promise<Array> - 任务列表
权限: 无需权限(读取操作)
示例:
const tasks = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.getAll',
[]
);
console.log(`共有 ${tasks.length} 个计划任务`);
tasks.forEach(task => {
console.log(`- ${task.id}: ${task.programName} (${task.triggerType})`);
});
ScheduleTask.setEnabled(taskId, enabled)启用/禁用计划任务。
参数:
taskId (string, 必需): 任务IDenabled (boolean, 必需): 是否启用返回值: Promise<boolean> - 是否成功
权限: 需要 SCHEDULE_TASK_MANAGE 权限
示例:
// 启用任务
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.setEnabled',
['task_1234567890_abc123', true]
);
// 禁用任务
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.setEnabled',
['task_1234567890_abc123', false]
);
任务信息对象包含以下字段:
{
id: string, // 任务ID(自动生成)
taskType: string, // 任务类型:'program' | 'command' | 'service'
programName?: string, // 程序名称(taskType === 'program' 时)
runInBackground?: boolean, // 是否以后台方式启动程序(taskType === 'program' 时,默认 true)
command?: string, // 命令(taskType === 'command' 时)
serviceId?: string, // 服务 ID(taskType === 'service' 时)
serviceAction?: string, // 服务操作:'start' | 'stop'(taskType === 'service' 时)
triggerType: string, // 触发类型
triggerConfig: Object, // 触发配置
enabled: boolean, // 是否启用
createdAt: number, // 创建时间戳(毫秒)
updatedAt: number, // 更新时间戳(毫秒)
lastRunAt: number, // 最后运行时间戳(毫秒),0 表示未运行
runCount: number, // 运行次数
createdBy: string, // 创建者(程序名称或PID)
requiresStartupPermission: boolean // 是否需要系统启动权限
}
// 在程序的 __init__ 方法中
async __init__(pid, initArgs) {
this.pid = pid;
try {
// 创建系统启动后的计划任务(需要危险权限)
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'filemanager',
triggerType: 'SYSTEM_STARTUP',
triggerConfig: {},
enabled: true
}, true] // requiresStartupPermission = true
);
console.log('计划任务创建成功:', taskId);
} catch (error) {
if (error.message.includes('没有权限')) {
console.error('权限不足,无法创建系统启动后的计划任务');
} else {
console.error('创建计划任务失败:', error.message);
}
}
}
// 创建每天 09:30 运行的任务
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'terminal',
triggerType: 'SPECIFIC_TIME',
triggerConfig: {
time: '09:30'
},
enabled: true
}, false]
);
// 创建工作时间(09:00-18:00)每 30 分钟运行一次的任务
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'musicplayer',
triggerType: 'TIME_RANGE',
triggerConfig: {
startTime: '09:00',
endTime: '18:00',
interval: 30
},
enabled: true
}, false]
);
// 创建每 60 分钟运行一次的任务
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'timer',
triggerType: 'INTERVAL',
triggerConfig: {
interval: 60
},
enabled: true
}, false]
);
// 创建系统关闭前执行的任务
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
programName: 'settings',
triggerType: 'SYSTEM_SHUTDOWN',
triggerConfig: {},
enabled: true
}, false]
);
// 创建每天 09:00 启动通知服务的任务
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
taskType: 'service',
serviceId: 'notice',
serviceAction: 'start',
triggerType: 'SPECIFIC_TIME',
triggerConfig: { time: '09:00' },
enabled: true
}, false]
);
// 创建系统关闭前停止某服务的任务
const taskId2 = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[{
taskType: 'service',
serviceId: 'notice',
serviceAction: 'stop',
triggerType: 'SYSTEM_SHUTDOWN',
triggerConfig: {},
enabled: true
}, false]
);
// 获取所有任务
const tasks = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.getAll',
[]
);
// 查找特定程序的任务
const fileManagerTasks = tasks.filter(task =>
task.programName === 'filemanager'
);
// 禁用所有文件管理器任务
for (const task of fileManagerTasks) {
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.setEnabled',
[task.id, false]
);
}
// 删除特定任务
await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.delete',
[taskId]
);
SCHEDULE_TASK_CREATE 权限(特殊权限,需要用户确认)SCHEDULE_TASK_STARTUP 权限(危险权限,仅管理员可授予)SCHEDULE_TASK_MANAGE 权限(特殊权限,需要用户确认)autoStart=true 的程序autoStart=true 的程序autoStart=true 的程序scheduledTask: true 标志,绕过 autoStart 权限检查HH:mm(24小时制)'09:30'、'18:00'、'23:59'TIME_RANGE 和 INTERVAL 类型的 interval 参数必须是整数,且至少为 1 分钟INTERVAL 类型任务创建后立即执行一次,然后按间隔重复执行SYSTEM_STARTUP 任务在系统启动完成后执行SYSTEM_SHUTDOWN 任务在系统关闭前执行(页面卸载时)LocalSData.jsonrunCount)和最后运行时间(lastRunAt)所有 API 调用都应该使用 try-catch 处理错误:
try {
const taskId = await ProcessManager.callKernelAPI(
this.pid,
'ScheduleTask.create',
[taskConfig, false]
);
console.log('任务创建成功:', taskId);
} catch (error) {
if (error.message.includes('没有权限')) {
console.error('权限不足:', error.message);
} else if (error.message.includes('程序不存在')) {
console.error('程序不存在:', error.message);
} else if (error.message.includes('无效的触发类型')) {
console.error('触发类型错误:', error.message);
} else {
console.error('创建任务失败:', error.message);
}
}
最后更新: 2026-01-06
维护者: ZerOS 安全团队