使用bat和使用C#操作Windows计划任务程序

有两种方式可以创建Windows计划任务程序

  1. bat脚本命令schtasks /create根据模板来创建计划任务
  2. 使用微软提供的Microsoft.Win32.TaskScheduler进行创建计划任务

两者的创建互有优劣:

bat脚本创建可以根据模板创建,比较简单方便;但是无法创建触发器需要特定用户,并且该用户设置了密码。(例如:触发器是A账户登录时,并且A账户有密码)

Microsoft.Win32.TaskScheduler创建计划任务比较复杂,但是可以创建触发器的特定用户设置了密码。

先介绍第一种bat脚本创建方式:

  1. 先手动在Windows任务计划程序——创建任务——手动把需要的任务AAA创建好
  2. 在C:\Windows\System32\Tasks中,找到AAA的文件复制出来,并且把名字改成AAA.xml。文件头必须是utf-16,不然创建任务时会提示读取xml失败
    <?xml version="1.0" encoding="UTF-16"?>
  3. 然后使用bat将xml模板的操作替换成特定的操作(例如执行某个exe),bat替换xml字符串可以参考我的另一篇文章:使用bat操作替换XML文件的字符串
  4. 使用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任务计划程序的一些注意事项

  1. 多个触发器是或的关系
  2. 触发器“启动时”,重启和关机启动都不起作用
posted @ 2023-04-18 16:06  log9527  阅读(671)  评论(0编辑  收藏  举报