博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用C#创建计划任务(How to create a Task Scheduler use C# )
阅读量:5996 次
发布时间:2019-06-20

本文共 9680 字,大约阅读时间需要 32 分钟。

本文主要讲解了如何使用C#来创建windows计划任务。

 

  •  需求:在不定时间段运行多个后台程序(winfrom,wpf,console,等等)用于更新数据。
  •  问题:为什么要使用计划任务,而不直接在程序中使用一个计时器来触发呢?

    •  答:最明显的一点,使用计时器程序一直在后台运行着,但需求中只需要一天运行一次,或一个月运行一次。一直后台跑着计时这不白浪费CPU资源么。
  •  解决方案:
    • 使用windows自带的计划任务 在控制面板中可以看到,手动新建计划任务。
    • 使用微软自带的类库TaskScheduler("c:\windows\system32\taskchd.dll")来创建
    • 使用Process.Star() dos命令来创建计划任务
      • dos命令运行scheduler.exe 最简单实例:

        schtasks /create /sc minute /mo 1 /tn MyTask /tr calc.exe /st 09:00  //从9点开始每隔一分钟运行一次记事本

        具体帮助文档可在cmd命令框输入:

        >schtasks /?  

        >schtasks /create /?  

        >schtasks /delete /?

        >schtasks /query /?

        >schtasks /change /?

      • 还可参照:

 

解决方案开始:

這里选用微软自带的类库TaskScheduler,下面是封装过的代码,包含了删除计划任务、判断计划任务是否存在、获取所有的计划任务、创建计划任务 。(具体看详细注释):

 

获取计划任务的列表:

     ///         /// get all tasks        ///         public static IRegisteredTaskCollection GetAllTasks()        {            TaskSchedulerClass ts = new TaskSchedulerClass();            ts.Connect(null, null, null, null);            ITaskFolder folder = ts.GetFolder("\\");            IRegisteredTaskCollection tasks_exists = folder.GetTasks(1);            return tasks_exists;        }
View Code

 

判断计划任务是否存在:

///         /// check task isexists        ///         ///         /// 
public static bool IsExists(string taskName) { var isExists = false; IRegisteredTaskCollection tasks_exists = GetAllTasks(); for (int i = 1; i <= tasks_exists.Count; i++) { IRegisteredTask t = tasks_exists[i]; if (t.Name.Equals(taskName)) { isExists=true; break; } } return isExists; }
View Code

 

删除计划任务:

///         /// delete task        ///         ///         private static void DeleteTask(string taskName)        {            TaskSchedulerClass ts = new TaskSchedulerClass();            ts.Connect(null, null, null, null);            ITaskFolder folder = ts.GetFolder("\\");            folder.DeleteTask(taskName, 0);        }
View Code

 

创建计划任务:

///         /// create scheduler        ///         ///         ///         ///         ///         ///         ///         /// 
public static _TASK_STATE CreateTaskScheduler(string creator, string taskName, string path,string interval,string startBoundary,string description) { try { if (IsExists(taskName)) { DeleteTask(taskName); } //new scheduler TaskSchedulerClass scheduler = new TaskSchedulerClass(); //pc-name/ip,username,domain,password scheduler.Connect(null, null, null, null); //get scheduler folder ITaskFolder folder = scheduler.GetFolder("\\"); //set base attr ITaskDefinition task = scheduler.NewTask(0); task.RegistrationInfo.Author = creator;//creator task.RegistrationInfo.Description = description;//description //set trigger (IDailyTrigger ITimeTrigger) ITimeTrigger tt = (ITimeTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME); tt.Repetition.Interval = interval;// format PT1H1M==1小时1分钟 设置的值最终都会转成分钟加入到触发器 tt.StartBoundary = startBoundary;//start time //set action IExecAction action = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC); action.Path = path;//计划任务调用的程序路径 task.Settings.ExecutionTimeLimit = "PT0S"; //运行任务时间超时停止任务吗? PTOS 不开启超时 task.Settings.DisallowStartIfOnBatteries = false;//只有在交流电源下才执行 task.Settings.RunOnlyIfIdle = false;//仅当计算机空闲下才执行 IRegisteredTask regTask = folder.RegisterTaskDefinition(taskName, task, (int)_TASK_CREATION.TASK_CREATE, null, //user null, // password _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, ""); IRunningTask runTask = regTask.Run(null); return runTask.State ; } catch (Exception ex) { throw ex; } }
View Code

 

完整代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using TaskScheduler;namespace McodsBgManager{    public class SchTaskExt    {        ///         /// delete task        ///         ///         private static void DeleteTask(string taskName)        {            TaskSchedulerClass ts = new TaskSchedulerClass();            ts.Connect(null, null, null, null);            ITaskFolder folder = ts.GetFolder("\\");            folder.DeleteTask(taskName, 0);        }        ///         /// get all tasks        ///         public static IRegisteredTaskCollection GetAllTasks()        {            TaskSchedulerClass ts = new TaskSchedulerClass();            ts.Connect(null, null, null, null);            ITaskFolder folder = ts.GetFolder("\\");            IRegisteredTaskCollection tasks_exists = folder.GetTasks(1);            return tasks_exists;        }        ///         /// check task isexists        ///         ///         /// 
public static bool IsExists(string taskName) { var isExists = false; IRegisteredTaskCollection tasks_exists = GetAllTasks(); for (int i = 1; i <= tasks_exists.Count; i++) { IRegisteredTask t = tasks_exists[i]; if (t.Name.Equals(taskName)) { isExists=true; break; } } return isExists; } /// /// create task /// /// /// /// /// ///
state
public static _TASK_STATE CreateTaskScheduler(string creator, string taskName, string path,string interval) { try { if (IsExists(taskName)) { DeleteTask(taskName); } //new scheduler TaskSchedulerClass scheduler = new TaskSchedulerClass(); //pc-name/ip,username,domain,password scheduler.Connect(null, null, null, null); //get scheduler folder ITaskFolder folder = scheduler.GetFolder("\\"); //set base attr ITaskDefinition task = scheduler.NewTask(0); task.RegistrationInfo.Author = "McodsAdmin";//creator task.RegistrationInfo.Description = "...";//description //set trigger (IDailyTrigger ITimeTrigger) ITimeTrigger tt = (ITimeTrigger)task.Triggers.Create(_TASK_TRIGGER_TYPE2.TASK_TRIGGER_TIME); tt.Repetition.Interval = interval;// format PT1H1M==1小时1分钟 设置的值最终都会转成分钟加入到触发器 tt.StartBoundary = "2015-04-09T14:27:25";//start time //set action IExecAction action = (IExecAction)task.Actions.Create(_TASK_ACTION_TYPE.TASK_ACTION_EXEC); action.Path = path; task.Settings.ExecutionTimeLimit = "PT0S"; //运行任务时间超时停止任务吗? PTOS 不开启超时 task.Settings.DisallowStartIfOnBatteries = false;//只有在交流电源下才执行 task.Settings.RunOnlyIfIdle = false;//仅当计算机空闲下才执行 IRegisteredTask regTask = folder.RegisterTaskDefinition(taskName, task, (int)_TASK_CREATION.TASK_CREATE, null, //user null, // password _TASK_LOGON_TYPE.TASK_LOGON_INTERACTIVE_TOKEN, ""); IRunningTask runTask = regTask.Run(null); return runTask.State ; } catch (Exception ex) { throw ex; } } }}
View Code

 

SchTaskExt.cs封装好了如何使用呢?

btnSetup_Click的代码如下:此处使用的是calc.exe做例。

private void btnSetup_Click(object sender, RoutedEventArgs e)        {            //创建者            var creator = "Tonge";            //计划任务名称            var taskName = "CalcTask";            //执行的程序路径            var path = "C:\\Windows\\System32\\calc.exe";            //计划任务执行的频率 PT1M一分钟  PT1H30M 90分钟            var interval = "PT1M";            //开始时间 请遵循 yyyy-MM-ddTHH:mm:ss 格式            var startBoundary = "2015-04-09T14:27:25";            var description = "this is description";            _TASK_STATE state = SchTaskExt.CreateTaskScheduler(creator, taskName, path, interval, startBoundary,description);            if (state == _TASK_STATE.TASK_STATE_RUNNING)            {                MessageBox.Show("计划任务部署成功!");            }        }

 

 

运行成功后:

 

可以看到calc.exe已经跑起来了,接下来我们在控制面板找到计划任务窗口看看。

好了 大功告成!

 

注意

1.引用taskchd.dll后选中按下F4在属性中将 嵌入互操作类型 改为 False (没设置会报一个错误: 无法嵌入互操作类型“TaskScheduler.TaskSchedulerClass”。请改用适用的接口。 )

2.所有操作都需要实例化schdule后进行connection:schdule.Connec("pc-name 或者 ip","username","domain","password")

3.触发器类型有多种选择(按天IDailyTrigger,按分钟ITimeTrigger));

触发频率(Interval)的格式需要遵循"PT1H1M"这样的格式;

起始时间需要遵循"YYYY-MM-DDThh:mm:ss"这样的格式。

4.计划任务运行的实例好像只能是唯一的,因为目前的情况这个calc可以正常运行第一次,第二次就被拒绝请求:

操作员或系统管理员拒绝了请求。(0x800710E0) ,这个错误在网上并没有找到解决方案,如下图。

后来在网上搜到 ,但是按照设置后仍没得到解决,官方也没有这个错误代码()。

所以我理解成这个计划任务只能运行一个实例,这个实例没有结束之前,如果到达下一次触发周期,则会被拒绝计划请求。

 

另:如有其它诠释还请指明,非常感谢!

 

完!

 

转载地址:http://kwqlx.baihongyu.com/

你可能感兴趣的文章
关于java中启动项目后,出现404的一个小问题
查看>>
ubuntu系统中Qt creator 编辑和应用使用中文输入法
查看>>
scalar UDFs performance issue
查看>>
【转载】React初学者入门须知
查看>>
es6合并对象
查看>>
python3-赋值与深浅拷贝(转载速查)
查看>>
ORM 进阶操作
查看>>
java的基本变量分类
查看>>
m_Orchestrate learning system---三十、项目中的dist文件一般是做什么的
查看>>
mysqli数据库操作简单实例
查看>>
P1133 教主的花园
查看>>
windows下以及Linux环境下安装activeMQ
查看>>
JS子节点删除操作小记
查看>>
Linux 下找出超過某些容量的檔案
查看>>
Nginx反向代理和负载均衡的配置
查看>>
编译原理--LR(1)分析表构建--JavaScript版
查看>>
整合ucenter经典教程
查看>>
mogodb(1) 简介
查看>>
使用wireshark抓取TCP包分析1
查看>>
LeetCode-15-3Sum
查看>>