使用bat和使用C#操作Windows计划任务程序
有两种方式可以创建Windows计划任务程序
- bat脚本命令schtasks /create根据模板来创建计划任务
-
使用微软提供的Microsoft.Win32.TaskScheduler进行创建计划任务
两者的创建互有优劣:
bat脚本创建可以根据模板创建,比较简单方便;但是无法创建触发器需要特定用户,并且该用户设置了密码。(例如:触发器是A账户登录时,并且A账户有密码)
Microsoft.Win32.TaskScheduler创建计划任务比较复杂,但是可以创建触发器的特定用户设置了密码。
先介绍第一种bat脚本创建方式:
- 先手动在Windows任务计划程序——创建任务——手动把需要的任务AAA创建好
- 在C:\Windows\System32\Tasks中,找到AAA的文件复制出来,并且把名字改成AAA.xml。文件头必须是utf-16,不然创建任务时会提示读取xml失败
<?xml version="1.0" encoding="UTF-16"?>
- 然后使用bat将xml模板的操作替换成特定的操作(例如执行某个exe),bat替换xml字符串可以参考我的另一篇文章:使用bat操作替换XML文件的字符串
- 使用schtasks /create命令创建
rem 根据模板来创建计划任务 schtasks /create /ru "%UserId%" /rp "" /tn "%TaskName%" /xml "%XmlName%" /F
其中/ru 表示使用指定用户帐户的权限运行任务。/rp 指定的用户帐户的密码。 /tn 任务名称。 /xml xml模板文件(如果模板不在同一目录,需要完整路径)。 /f 如果指定的任务已经存在,则指定创建任务并取消警告。
接着介绍第二种使用Microsoft.Win32.TaskScheduler创建方式:
public class SystemTaskScheduler { /// <summary> /// 获取所有任务 /// </summary> public static TaskCollection GetAllTasks() { TaskService ts = new TaskService(); var folder = ts.GetFolder("\\"); var tasks_exists = folder.GetTasks(); folder.Dispose(); ts.Dispose(); return tasks_exists; } /// <summary> /// 检查任务是否存在 /// </summary> /// <param name="taskName"></param> /// <returns></returns> public static bool IsExists(string taskName) { var isExists = false; TaskCollection tasks_exists = GetAllTasks(); for (int i = 0; i < tasks_exists.Count; i++) { var task = tasks_exists[i]; if (task.Name.Equals(taskName)) { isExists = true; break; } } return isExists; } /// <summary> /// 删除指定任务 /// </summary> /// <param name="taskName"></param> public static void DeleteTask(string taskName) { TaskService ts = new TaskService(); var folder = ts.GetFolder("\\"); folder.DeleteTask(taskName); folder.Dispose(); ts.Dispose(); } /// <summary> /// 创建指定任务 /// </summary> /// <param name="taskName"></param> /// <param name="path"></param> /// <param name="userId"></param> /// <param name="description"></param> /// <param name="creator"></param> /// <param name="delay">延时启动时间</param> /// <returns></returns> public static bool CreateTaskScheduler(string taskName, string path, string userId, string creator = "", string description = "", TimeSpan? delay = null) { try { if (IsExists(taskName)) { DeleteTask(taskName); } TaskService service = new TaskService(); TaskDefinition definition = service.NewTask(); definition.RegistrationInfo.Author = creator; definition.RegistrationInfo.Description = description; definition.RegistrationInfo.Version = new Version(1, 0, 0); definition.RegistrationInfo.Date = DateTime.Now; //会话改变 SessionStateChangeTrigger sessionStateChangeTrigger = new SessionStateChangeTrigger(); sessionStateChangeTrigger.StateChange = TaskSessionStateChangeType.SessionUnlock; // 这里不需要特定账户的密码 sessionStateChangeTrigger.UserId = userId; definition.Triggers.Add(sessionStateChangeTrigger); //用户登录时启动 LogonTrigger logonTrigger = new LogonTrigger(); logonTrigger.Enabled = true; logonTrigger.UserId = userId; if (delay.HasValue) { logonTrigger.Delay = delay.Value; } definition.Triggers.Add(logonTrigger); definition.Actions.Add(new ExecAction(path, "", null)); definition.Principal.RunLevel = TaskRunLevel.Highest; definition.Principal.UserId = userId; definition.Principal.LogonType = TaskLogonType.InteractiveToken; //td.Settings.ExecutionTimeLimit = ; //运行任务时间超时停止任务吗? definition.Settings.DisallowStartIfOnBatteries = false;//只有在交流电源下才执行 definition.Settings.RunOnlyIfIdle = false;//仅当计算机空闲下才执行 definition.Settings.Enabled = true; definition.Settings.AllowDemandStart = true; definition.Settings.AllowHardTerminate = true; var task = service.RootFolder.RegisterTaskDefinition(taskName, definition, TaskCreation.CreateOrUpdate, userId, null, TaskLogonType.None, ""); //task.Run(); return true; } catch (Exception ex) { H3CLog.Error(ex); return false; } } }
题外话:Windows任务计划程序的一些注意事项
- 多个触发器是或的关系
- 触发器“启动时”,重启和关机启动都不起作用