windows系统,如何创建任务计划程序

  在windows系统中,我们总能感受到一些开机或者登录后,就会弹出软件更新的小弹窗,或者其他软件弹出的各种小窗口。如何实现这种功能呢?

  实现开机或者登录后检测更新、弹出小弹窗,有两种方法。一种是写一个小程序,然后加入到开机自启注册表中,让系统运行它;另一种是写一个任务计划程序,由它控制更新或者执行其他任务。

  甚至,如果开机自启的小程序需要管理员权限运行,而程序又没有windows认证的安全证书,开机自启都不会启动它。但任务计划程序是直接运行这个程序的,即使需要管理员权限,因为创建任务计划程序本就需要管理员权限创建。

         

 

 

  创建一个任务计划程序,很简单,首先需要我们引入一个Microsoft.Win32.TaskScheduler.dll(下载地址)。

  引入dll后,我们需要用到TaskService类,它能够管理计算机上的服务。

1、TaskService的简单用法

/// <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();
}

2、创建一个任务计划程序

  创建一个任务计划程序,首先需要获得当前计算机的任务计划程序集,然后定义一个任务。直接new一个TaskService对象,然后调用TaskService 对象的方法NewTask()获取到一个TaskDefinition的对象,该对象将是我们设置任务信息的核心操作者。

  1. TaskDefinition 的 RegistrationInfo,就是我们看到的任务里常规的显示信息,注入创建者、创建时间、版本、描述等等信息;
  2. TaskDefinition 的 Triggers 定义什么时候触发程序执行,开机后?登录后?还是延迟启动?等等不同的类型,这就是任务里的触发器。 不同的触发器,内容不一样(不详述),定义好Trigger,然后将对象加入TaskDefinition 的Triggers集合里。当然,一个任务也可以有多个触发器;
  3. TaskDefinition 的 Actions 将定义触发器触发后,执行什么操作,比如启动程序?下载数据?上报数据?还是其他的。同理,Action也可以有多个。
  4. TaskDefinition 的 Settings 可以配置任务的条件和设置。比如,某些操作必须要先接通电源。
  5. 最后,只需要调用TaskService的RootFolder.RegisterTaskDefinition,注册该任务对象,就可以了。

  下面是我简单定义了一个用户登录则启动的一个示例:

 /// <summary>
 /// 创建指定任务
 /// </summary>
 /// <param name="taskName"></param>
 /// <param name="path"></param>
 /// <param name="description"></param>
 /// <param name="creator"></param>
 /// <param name="delay">延时启动时间</param>
 /// <returns></returns>
 public static TaskState CreateTaskScheduler(string taskName, string path, string description = "", string creator = "", 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;
         //开机自启
         //BootTrigger bootTrigger = new BootTrigger();
         //// bootTrigger.StartBoundary = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
         //bootTrigger.Enabled = true;
         //if (delay.HasValue)
         //{
         //    bootTrigger.Delay = delay.Value;
         //}
         ////设置重复任务间隔时间
         ////bootTrigger.Repetition.Interval = TimeSpan.FromDays(1);
         //td.Triggers.Add(bootTrigger);
         //用户登录时启动
         LogonTrigger logonTrigger = new LogonTrigger();
         //logonTrigger.StartBoundary = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
         logonTrigger.Enabled = true;
         if (delay.HasValue)
         {
             logonTrigger.Delay = delay.Value;
         }
         //设置重复任务间隔时间
         //logonTrigger.Repetition.Interval = TimeSpan.FromDays(1);
         definition.Triggers.Add(logonTrigger);


         definition.Actions.Add(new ExecAction(path, "", null));

         definition.Principal.RunLevel = TaskRunLevel.Highest;
         definition.Principal.UserId = "Administrators";
         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,
             "Administrators", null,
             TaskLogonType.Group,
             "");
         //task.Run();
         return task.State;

     }
     catch (Exception ex)
     {
         throw ex;
     }
 }

3、创建一个任务

  由于任务是可以绕开安全检查的,但创建一个任务是绕不开的,因此,创建一个任务,需要使用管理员权限。

  首先,检测管理员权限,然后才是创建任务。 

WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);
void CreateTask()
{
    string taskName = "NigleAutoStart";
    var creator = "Y&Z";
    var path = @"D:\WpfApp1.exe";//任务动作为启动D盘下的程序
    var description = "开机自启";
    Console.WriteLine("设置任务");
    var state = SystemTaskScheduler.CreateTaskScheduler(taskName, path, description, creator);

    Console.WriteLine($"任务设置成功:{state}");
    if (state == Microsoft.Win32.TaskScheduler.TaskState.Running)
    {
        System.Threading.Thread.Sleep(2000);
        SystemTaskScheduler.DeleteTask(taskName);
        Console.WriteLine("删除任务");
    }
}

 

posted @ 2021-09-11 18:02  一只独行的猿  阅读(1864)  评论(0编辑  收藏  举报