背景:我做了一個事情是要自己提前創建好很多要定時執行的任務,在我不在的時候自動執行這些程序,以保證我的工作能無人值守,那么我就需要建立系統計划任務來幫我完成這件事情,當然用腦子想想如何實現,很簡單,每個程序員都能想到,甚至是不是程序員的人都能想到如何去操作,但實際操作過程中會遇到很多坑,我現在就記錄一下這些我遇到的坑,讓大家避免跟我一樣遇到后花費不必要的時間。
廢話不多說,直接看方案
步驟:
先找到可以實現這個邏輯的類或者是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
