[经验分享]C# 操作Windows系统计划任务

背景:我做了一个事情是要自己提前创建好很多要定时执行的任务,在我不在的时候自动执行这些程序,以保证我的工作能无人值守,那么我就需要建立系统计划任务来帮我完成这件事情,当然用脑子想想如何实现,很简单,每个程序员都能想到,甚至是不是程序员的人都能想到如何去操作,但实际操作过程中会遇到很多坑,我现在就记录一下这些我遇到的坑,让大家避免跟我一样遇到后花费不必要的时间。

废话不多说,直接看方案

步骤:

先找到可以实现这个逻辑的类或者是dll,nuget包等等都可以,我下面使用的是直接使用Windows系统中的dll文件来实现

按照以下步骤做一定能达成你的目标

1.进入C:\Windows\System32\目录下,找到taskschd.dll文件,这个文件主要就是用来操作Windows计划任务的

2.将taskschd.dll引入到项目中(注意【嵌入互操作类型】属性要为false才行,否则会有报错),然后参考:https://www.cnblogs.com/tonge/p/4410066.html,如果嫌麻烦,可以直接看下面的代码

  1 #region Task
  2     /// <summary>
  3     /// delete task
  4     /// </summary>
  5     /// <param name="taskName"></param>
  6     private static void DeleteTask(string taskName)
  7     {
  8       TaskSchedulerClass ts = new TaskSchedulerClass();
  9       ts.Connect(null, null, null, null);
 10       ITaskFolder folder = ts.GetFolder("\\");
 11       folder.DeleteTask(taskName, 0);
 12     }
 13 
 14     /// <summary>
 15     /// get all tasks
 16     /// </summary>
 17     public static IRegisteredTaskCollection GetAllTasks()
 18     {
 19       TaskSchedulerClass ts = new TaskSchedulerClass();
 20       ts.Connect(null, null, null, null);
 21       ITaskFolder folder = ts.GetFolder("\\");
 22       IRegisteredTaskCollection tasks_exists = folder.GetTasks(1);
 23       return tasks_exists;
 24     }
 25     /// <summary>
 26     /// check task isexists
 27     /// </summary>
 28     /// <param name="taskName"></param>
 29     /// <returns></returns>
 30     public static bool IsExists(string taskName)
 31     {
 32       var isExists = false;
 33       IRegisteredTaskCollection tasks_exists = GetAllTasks();
 34       for (int i = 1; i <= tasks_exists.Count; i++)
 35       {
 36         IRegisteredTask t = tasks_exists[i];
 37         if (t.Name.Equals(taskName))
 38         {
 39           isExists = true;
 40           break;
 41         }
 42       }
 43       return isExists;
 44     }
 45 
 46     /// <summary>
 47     /// create scheduler
 48     /// </summary>
 49     /// <param name="creator"></param>
 50     /// <param name="taskName"></param>
 51     /// <param name="path"></param>
 52     /// <param name="interval"></param>
 53     /// <param name="startBoundary"></param>
 54     /// <param name="description"></param>
 55     /// <returns></returns>
 56     public static _TASK_STATE CreateTaskScheduler(string creator, string taskName, string path, string interval, string startBoundary, string description)
 57     {
 58       try
 59       {
 60         if (IsExists(taskName))
 61         {
 62           DeleteTask(taskName);
 63         }
 64 
 65         //new scheduler
 66         TaskSchedulerClass scheduler = new TaskSchedulerClass();
 67         //pc-name/ip,username,domain,password
 68         scheduler.Connect(null, null, null, null);
 69         //get scheduler folder
 70         ITaskFolder folder = scheduler.GetFolder("\\");
 71 
 72 
 73         //set base attr 
 74         ITaskDefinition task = scheduler.NewTask(0);
 75         task.RegistrationInfo.Author = creator;//creator
 76         task.RegistrationInfo.Description = description;//description
 77 
 78         //set trigger  (IDailyTrigger ITimeTrigger)
 79         ITimeTrigger tt = (ITimeTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME);
 80         tt.Repetition.Interval = interval;// format PT1H1M==1小时1分钟 设置的值最终都会转成分钟加入到触发器
 81         tt.StartBoundary = startBoundary;//start time
 82 
 83         //set action
 84         IExecAction action = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC);
 85         action.Path = path;//计划任务调用的程序路径
 86 
 87         task.Settings.ExecutionTimeLimit = "PT0S"; //运行任务时间超时停止任务吗? PTOS 不开启超时
 88         task.Settings.DisallowStartIfOnBatteries = false;//只有在交流电源下才执行
 89         task.Settings.RunOnlyIfIdle = false;//仅当计算机空闲下才执行
 90 
 91         IRegisteredTask regTask = folder.RegisterTaskDefinition(taskName, task,
 92                                                             (int)_TASK_CREATION.TASK_CREATE,
 93                                                             null, //user
 94                                                             null, // password
 95                                                             _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN,
 96                                                             "");
 97         IRunningTask runTask = regTask.Run(null);
 98         return runTask.State;
 99 
100       }
101       catch (Exception ex)
102       {
103         throw ex;
104       }
105 
106     }
107     #endregion
108 
109     private static void TestTaskScheduler()
110     {
111       //创建者
112       var creator = "Tonge";
113       //计划任务名称
114       var taskName = "CalcTask";
115       //执行的程序路径
116       var path = "C:\\Windows\\System32\\calc.exe";
117       //计划任务执行的频率 PT1M一分钟  PT1H30M 90分钟
118       var interval = "PT1M";
119       //开始时间 请遵循 yyyy-MM-ddTHH:mm:ss 格式
120       var startBoundary = "2019-10-15T14:27:25";
121       var description = "this is description";
122       
123       _TASK_STATE state = CreateTaskScheduler(creator, taskName, path, interval, startBoundary, description);
124       if (state == _TASK_STATE.TASK_STATE_RUNNING)
125       {
126         Console.WriteLine("计划任务部署成功!");
127       }
128     }

3.创建控制台程序(这个我就不用讲解了,你们懂的),直接粘贴进去即可

4.直接编译后运行,可能会遇到没有权限的问题,那么就需要用到下一个参考:https://www.cnblogs.com/babycool/p/3569183.html

5.解决管理员身份运行程序后,一定要关闭Visual Studio 工具,然后打开的时候使用管理员身份运行工具,再次编译,会发现成功了,创建的计划任务也顺利执行了

6.这时便大功告成,如有其他建议,可以留言给我,非常欢迎!

 

附其他参考:

https://archive.codeplex.com/?p=taskscheduler

https://blog.csdn.net/bubu05690523/article/details/41282919

https://dahall.github.io/TaskScheduler/html/R_Project_TaskScheduler.htm

https://docs.microsoft.com/zh-cn/windows/win32/taskschd/schtasks?redirectedfrom=MSDN#creating-a-task

【文中引用】https://www.cnblogs.com/tonge/p/4410066.html

【文中引用】https://www.cnblogs.com/babycool/p/3569183.html

 

posted @ 2019-10-15 15:27  MartyZane  阅读(1814)  评论(0编辑  收藏  举报