如何在 C# 中使用 TaskScheduler 设置“仅在登录时运行”和“运行方式”?

Posted

技术标签:

【中文标题】如何在 C# 中使用 TaskScheduler 设置“仅在登录时运行”和“运行方式”?【英文标题】:How to set “run only if logged in” and “run as” with TaskScheduler in C#? 【发布时间】:2017-09-21 19:04:50 【问题描述】:

我正在尝试使用 c# Task Scheduler Managed Wrapper 在 Windows 系统上以编程方式生成计划任务。我可以生成任务,但只有在帐户登录时才能运行它:

我一直在环顾四周,发现去年提出的另一个 SO 问题,但要么有其他相关设置未提及,要么代码库中的某些内容从那时起发生了变化:

How to set "run only if logged in" and "run as" with TaskScheduler in C#?

我认为这种方法可能是正确的,但是当我尝试它时,我收到一条令人困惑的错误消息:

Task Scheduler 2.0 (1.2) 不支持设置此属性。您必须使用 InteractiveToken 才能让任务在当前用户会话中运行。

我使用的代码如下:

    public static void ScheduleTask(string machineName, string taskName, string taskAccount, string password)
    
        using (TaskService ts = new TaskService(machineName))
        
            TaskDefinition td = ts.NewTask();

            td.Principal.RunLevel = TaskRunLevel.Highest;
            td.Principal.UserId = WindowsIdentity.GetCurrent().Name;
            td.Principal.LogonType = TaskLogonType.InteractiveToken;

            td.Settings.MultipleInstances = TaskInstancesPolicy.IgnoreNew;
            td.Settings.DisallowStartIfOnBatteries = false;
            td.Settings.StopIfGoingOnBatteries = false;
            td.Settings.StartWhenAvailable = true;
            //td.Settings.RunOnlyIfLoggedOn = true;
            td.Settings.Enabled = true;
            td.Settings.Hidden = false;
            td.Settings.AllowHardTerminate = true;
            td.Settings.ExecutionTimeLimit = new TimeSpan();

            var tt = new SessionStateChangeTrigger();
            tt.StartBoundary = DateTime.Now.AddMinutes(1);
            tt.UserId = taskAccount;
            tt.StateChange = TaskSessionStateChangeType.RemoteConnect;
            tt.Repetition.Interval = TimeSpan.FromMinutes(1);
            tt.Repetition.StopAtDurationEnd = false;
            td.Triggers.Add(tt);

            td.Actions.Add("notepad.exe", "c:\\test.log");

            ts.RootFolder.RegisterTaskDefinition(taskName, td, TaskCreation.CreateOrUpdate, taskAccount, password, TaskLogonType.Password, null);
        
    

如果我使用有效的服务器、用户等运行此代码,它会生成一个没有问题的任务。如果我在“RunOnlyIfLoggedOn”参数中添加注释,它会生成我之前提到的错误。请注意,我将 LogonType 属性设置为 TaskLogonType.InteractiveToken,所以一定还有一些我遗漏的东西。

【问题讨论】:

【参考方案1】:

好的,有解决办法:

注册任务定义调用需要将其TaskLogonType 设置为Interactive Token。仅将 TaskDefinition Principal Logon 类型设置为使用交互式 Token 是行不通的。

RunOnlyIfLoggedOn 似乎只适用于早期版本的任务调度程序(v1,在 w2k3 等系统上)

【讨论】:

我知道已经有一段时间了,但请您提供任何代码示例,说明您是如何解决此问题的。 @bennygenel 我猜这个:ts.RootFolder.RegisterTaskDefinition(taskName, td, TaskCreation.CreateOrUpdate, taskAccount, password, TaskLogonType.InteractiveToken, null);

以上是关于如何在 C# 中使用 TaskScheduler 设置“仅在登录时运行”和“运行方式”?的主要内容,如果未能解决你的问题,请参考以下文章

如何区分任务计划程序 1.0 和任务计划程序 2.0?

TaskScheduler - 执行延续

使用 C# 任务计划库启用/禁用任务

大话Spark-源码之TaskScheduler

Spark TaskScheduler 概述

Spark实战_SparkContext原理剖析与源码分析