【问题标题】:Task Scheduler Managed Wrapper error Access denied任务计划程序托管包装错误访问被拒绝
【发布时间】:2016-11-30 13:12:15
【问题描述】:

我正在创建一个应用程序,该应用程序在首次登录时为每个用户创建计划任务。我正在使用 NuGet 包 Task Scheduler Managed Wrapper 2.5.21。当 exe 在登录时运行时,会出现拒绝访问错误。以管理员身份手动运行 exe 时,会创建计划任务。我该如何克服这个问题?

string installPath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);

using (TaskService ts = new TaskService())
{
    TaskDefinition td = ts.NewTask();

    td.Actions.Add(new ExecAction("MyExe.exe", null, installPath));
    td.Triggers.Add(new SessionStateChangeTrigger
    {
        StateChange = TaskSessionStateChangeType.SessionUnlock,
        UserId = Environment.UserName
    });

    td.Principal.RunLevel = TaskRunLevel.Highest;
    td.Principal.LogonType = TaskLogonType.InteractiveToken;
    ts.RootFolder.RegisterTaskDefinition("task_" + Environment.UserName, td);
}

【问题讨论】:

  • 我猜您的用户帐户不是管理员或高级用户,或者 UAC 最高?
  • 即使用户有管理员权限,也会发生错误。堆栈跟踪
  • 明确记录 here,第二个注释。因此,要么程序必须以 UAC 提升运行(登录时不会发生),要么管理员需要更改 c:\windows\tasks 的 ACL
  • 不需要管理员权限为自己创建任务,用于交互式令牌。我也遇到了类似的问题...只是无法在非特权帐户中使用 TaskService 创建任务...

标签: c# scheduled-tasks taskscheduler


【解决方案1】:

对于非管理或非提升用户,每种触发器类型都有一组限制。例如。您不能为其他人添加 OnLogon 触发器,只能为您自己添加。看起来您也根本无法添加SessionStateChangeTrigger

这是基于作者对我的问题的回答的工作示例: https://github.com/dahall/TaskScheduler/issues/58

var td = ts.NewTask();
td.Actions.Add("notepad", null, null);
td.Triggers.Add(new LogonTrigger { UserId = WindowsIdentity.GetCurrent().Name });
ts.RootFolder.RegisterTaskDefinition("Test", td);

注意:如果您在 UAC 下使用TaskRunLevel.Highest 为管理员创建任务,这只有在提升后才有可能(否则这将是一个使 UAC 无用的巨大漏洞)

注意:如果您为每个启动应用程序的用户创建任务 - 您必须在任务名称中包含用户 SID。即使将重命名用户,这也保证是唯一的。否则将被拒绝访问,因为其他用户已经创建了相同的任务(并且他拥有比您更多的权限)。考虑 DropBox、OneDrive、GoogleDrive - 它们都在任务名称中添加 SID。

这就是我最后的做法(包括Highest版本和普通版本的不同任务名称:

private static void CreateTask(string path, string taskFolder, bool highest)
{
    var sid = WindowsIdentity.GetCurrent().User.Value;
    var userId = WindowsIdentity.GetCurrent().Name;
    using (var ts = new TaskService())
    {
        var td = ts.NewTask();
        if (highest)
        {
            td.Principal.RunLevel = TaskRunLevel.Highest;
        }
        td.Actions.Add(path, "/a", null);
        td.Triggers.Add(new LogonTrigger { UserId = userId, });
        ts.RootFolder.RegisterTaskDefinition(taskFolder + "MyApp Task-" + sid + (highest ? "h" : ""), td);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-27
    • 2016-09-05
    • 2010-09-28
    • 2020-09-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多