How to list scheduled tasks in C#
Asked Answered
C

4

11

Before anyone says this is a duplicate, I already checked here, here, here, here, and a couple of other resources, including MS Task Scheduler Class documentation.

I wanted to be able to list the scheduled tasks on my servers using a C# program I´m developing. Some suggested schtasks.exe MS program, others a third-party library, which seems old and working only with .NET Framework 2.0 and others the MS Task Scheduler Class, which seems to be protected and I´m yet to see some example so I understand how I can use it, and others suggested even reading the XML files in each remote machine under C:\Windows\System32\Tasks folder.

My question is: are tasks in Windows that hard to work with using some VS built-in class? Do I have to jump through hoops in order to do something (kind of) silly like listing the tasks already scheduled in a machine?

Thank you,

EDIT:

I ended up using Process class and started schtasks.exe against all servers. Not exactly what I was looking for but it works. If anyone needs the code, just drop me a line and I post it here. Thanks.

Clot answered 28/12, 2016 at 16:25 Comment(6)
What does "seems to be protected" mean in the context of the MS Task Scheduler Class?Baste
@JimMischel, in [MS documentation] (msdn.microsoft.com/en-us/library/…) it says the constructor is protected.Clot
Yes, but TaskScheduler.Current is static and public, as is TaskScheduler.Default. The constructor is intended to be used only by derived classes. In any case, that class does not appear to be an interface to the operating system's list of scheduled tasks.Baste
Could you post your solution as an answer please.Chloroform
I'm surprised this doesn't exist in .Net Framework.Chloroform
sorry buddy, that was almost 4 years ago. I'm not working with Windows at all anymore (thank goodness). But if you really need it I can try to find the code in my backupsClot
O
11

Ah, System.Threading.TaskScheduler is for scheduling work units within a process, not related to the scheduled tasks that you can create from the administrative tools.

I would use a library like TaskScheduler - Googled to find, I do something similar with an awful COM wrapper from 2004 that I've been meaning to update. It makes it pretty easy to see what's in the scheduled tasks.

E.g. from their "Enumerate all tasks" example

void EnumAllTasks()
{
   using (TaskService ts = new TaskService())
      EnumFolderTasks(ts.RootFolder);
}

void EnumFolderTasks(TaskFolder fld)
{
   foreach (Task task in fld.Tasks)
      ActOnTask(task);
   foreach (TaskFolder sfld in fld.SubFolders)
      EnumFolderTasks(sfld);
}

void ActOnTask(Task t)
{
   // Do something interesting here
}
Obligation answered 29/12, 2016 at 22:29 Comment(1)
This library works a treat. The source code has now moved to github.com/dahall/TaskScheduler. You can download the nuget package from nuget.org/packages/TaskScheduler or using your package manager.Chloroform
M
4

In Visual Studio add the reference in COM\Type Libraries: TaskScheduler

and use the Taskschd API: https://learn.microsoft.com/en-us/windows/desktop/api/taskschd

This is an example of the way I'm doing it:

You retrieve the tasks at which you have access permissions, depending if you're running the code with a local or admin account.

My solution was doing this in a Windows Service with Local System account that runs in our servers.

using TaskScheduler;

void ProcessTaskFoler (ITaskFolder taskFolder)
{
    int idx;
    string name, path;
    _TASK_STATE state;

    IRegisteredTaskCollection taskCol = taskFolder.GetTasks((int)_TASK_ENUM_FLAGS.TASK_ENUM_HIDDEN);  // include hidden tasks, otherwise 0
    for (idx = 1; idx <= taskCol.Count; idx++)  // browse al tasks in folder
    {
        IRegisteredTask runTask = taskCol[idx];  // 1 based index

        name = runTask.Name;
        path = runTask.Path;
        state = runTask.State;
        // retrieve other properties...

        Console.WriteLine(path);
    }

    ITaskFolderCollection taskFolderCol = taskFolder.GetFolders(0);  // 0 = reserved for future use
    for (idx = 1; idx <= taskFolderCol.Count; idx++)  // recursively browse subfolders
        ProcessTaskFoler(taskFolderCol[idx]);  // 1 based index
}

void ParseScheduleTasks()
{
    ITaskService taskService = new TaskScheduler.TaskScheduler();
    taskService.Connect();

    ProcessTaskFoler(taskService.GetFolder("\\"));
}
Mcdaniel answered 15/11, 2018 at 15:31 Comment(0)
R
2

Why not use powershell inside of your C# code? Reference this for implementing powershell in your application.

And for finding scheduled tasks on a PC/server using powershell, here's the link to do that.

Combine both of them along with reading the powershell output in your C# app, and Voila.

Raman answered 28/12, 2016 at 16:45 Comment(1)
I just checked and apparently PowerShell Get-ScheduledTask and Get-ScheduledTaskInfo cmdlets can´t retrieve the "Run as user" field I was looking for. Maybe I will have to resort to schtask.exeClot
C
0
            using (TaskService ts = new TaskService())
            {
                Task t = ts.GetTask(TaskName);
                if (t != null)
                {
                   //Do your operation here
                }
            }     
Cost answered 12/11, 2021 at 8:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.