背景:我做了一个事情是要自己提前创建好很多要定时执行的任务,在我不在的时候自动执行这些程序,以保证我的工作能无人值守,那么我就需要建立系统计划任务来帮我完成这件事情,当然用脑子想想如何实现,很简单,每个程序员都能想到,甚至是不是程序员的人都能想到如何去操作,但实际操作过程中会遇到很多坑,我现在就记录一下这些我遇到的坑,让大家避免跟我一样遇到后花费不必要的时间。
废话不多说,直接看方案
步骤:
先找到可以实现这个逻辑的类或者是dll,nuget包等等都可以,我下面使用的是直接使用Windows系统中的dll文件来实现
按照以下步骤做一定能达成你的目标
1.进入C:WindowsSystem32目录下,找到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