Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Friday, January 11, 2008 1:28 PM
Hi,
I am trying to schedule a task via c# code(winforms). But before creating I would like to check whether a task of the same name already exists. I am trying to get a list of tasks using schtasks /query. But it gives other information as well ,like HostName, Status etc. I need only the list of TaskNames.
I tried the code as shown below. The strOutput shows headers, status, hostname and next time run along with TaskName. I need only Tasknames. Help would be appreciated.
private void button1_Click(object sender, EventArgs e)
{
ProcessStartInfo psi = new ProcessStartInfo("SCHTASKS", "/QUERY /fo table");
psi.RedirectStandardOutput = true;
psi.UseShellExecute = false;
Process p = Process.Start(psi);
p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived);
p.BeginOutputReadLine();
}
void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
//string str = "";
strOutput += e.Data+",";
}
private void button2_Click(object sender, EventArgs e)
{
label1.Text = strOutput;
}
All replies (3)
Friday, January 11, 2008 1:40 PM âś…Answered
You should consider using the COM interface instead as it is more reliable than parsing program output.
The Task Scheduler has undergone some changes in Vista so the exact code might be a little different if you're using Vista. The following article discusses how to use the COM interface to enumerate the scheduled tasks: http://msdn2.microsoft.com/en-us/library/aa446864.aspx. It is written for C++ but it will work in .NET if you first create an interop assembly by adding a COM reference to your project for the TS. You can then use GetTasks to retrieve the tasks.
There are a couple of TS wrappers floating around that you can use to save time if you don't want to build it yourself. There is also an MSDN article on how to use TS2. It is primary targeted for native code but it contains a sidebar entry for using it in C#: http://msdn.microsoft.com/msdnmag/issues/07/10/WindowsCPP/default.aspx
Michael Taylor - 1/11/08
Wednesday, May 22, 2013 4:11 AM
Hi Folks,
I do have a requirement:
1.Need to get the status of all scheduled tasks schduled in a remote machine
2.Based on status need to send an alert email
This is my sample code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32.TaskScheduler;
using System.Threading;
using System.Diagnostics;
using System.Net;
using System.Net.Mail;
using System.Data.SqlClient;
using System.Data;
using System.Devices;
//using System.Devices.RemoteDeviceManager;
//using System.Diagonistics.EventLog;
namespace TaskSchedulerRemote
{
class Program
{
//TaskService 01_server = getTaskService("\\\\123.122.222.222", "administrator", "domain1", "pwd0", true);
//TaskService 02_server = getTaskService("\\\\123.122.222.222", "administrator", "domain2", "pwd1", true);
static void Main(string[] args)
{
using (TaskService task = new TaskService())
{
TaskDefinition td = task.NewTask();
td.RegistrationInfo.Description = "RF Report";
td.Actions.Add(new ExecAction("notepad.exe", "c:\test.log", null));
while (true)
{
Task taskdDef = task.FindTask("RF Report");
//string registeredTask;
//string[] taskCollection = { "", "", "" };
//foreach (string str in taskCollection)
//{
//For Each registeredTask In taskCollection
switch (taskdDef.State)
{
case TaskState.Queued:
Console.WriteLine("Queued");
break;
case TaskState.Ready:
Console.WriteLine("Ready");
break;
case TaskState.Unknown:
Console.WriteLine("Unknown");
break;
case TaskState.Disabled:
Console.WriteLine("Disabled");
break;
case TaskState.Running:
Console.WriteLine("Running");
break;
}
Thread.Sleep(10000);
//MailMessage Msg = new MailMessage();
//MailAddress fromMail = new MailAddress("emailid");
//// Sender e-mail address.
//Msg.From = fromMail;
//// Recipient e-mail address.
//Msg.To.Add(new MailAddress("emailid"));
//Msg.Priority = MailPriority.High;
//// Subject of e-mail
//Msg.Subject = "Scheduled Task Status Report:" + System.DateTime.Now;
//Msg.Body += "<html><body><Table><tr><td>Hi All,</td></tr><tr><td>Please find below the status report of schduled task :</td></tr></Table></body></html><html><body>";
//Msg.Body += "<html><body><Table><tr><td>Regards,</td></tr><tr><td></td></tr><tr><td></td></tr>" +
//"<tr><td><b>NOTE: This is an automated mail. Please, do not reply.</b> </td></tr></table></body></html>";
//Msg.IsBodyHtml = true;
//string sSmtpServer = "";
//sSmtpServer = "mailservername";
//SmtpClient a = new SmtpClient();
//a.Host = sSmtpServer;
//a.EnableSsl = false;
//try
//{
// Console.WriteLine("Sending mail...");
// a.Send(Msg);
// Console.WriteLine("Mail was sent successfully!");
//}
//catch (Exception ep)
//{
// Console.WriteLine("failed to send mail:");
// Console.WriteLine(ep.Message);
//}
//}
}
string sSource = "MyCustom Group";
string sLog = "Application";
string sEvent = "";
if (!EventLog.SourceExists(sSource))
EventLog.CreateEventSource(sSource, sLog);
EventLog.WriteEntry(sSource, sEvent, EventLogEntryType.Error, 234);
}
}
}
}
Not sure how to connect to the remote server/machine and read and get the task status details and also need to amend that status details in email.
Could anyone please look into my code and suggest.
Many Thanks,
Sisir
Thursday, January 23, 2020 1:14 PM
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.IO;
using System.Linq;
namespace GetTaskSchedulerHistory
{
class Program
{
static void Main()
{
using (var session = new EventLogSession("BASWPVSQL01"))
{
var result =
GetCompletedScheduledTaskEventRecords(session, "DefectsDataPuller");
var response = result
.OrderByDescending(x => x.TimeCreated)
.Select(r => new { r.UserId,r.LogName,r.Task,CompletedTime = r.TimeCreated, r.TaskDisplayName, Props = string.Join(" | ", r.Properties.Select(p => p.Value)) })
.ToList();
//Writing the response to a text file, with a delimiter which I then exported to Excel
string fileName = "PATH_TO_FILE_TO_WRITE_THE_LOGS.TXT";
using (var fs = new StreamWriter(fileName))
{
foreach (var item in response)
{
fs.WriteLine(item.UserId + "||" + item.LogName +"||" + item.TaskDisplayName + "||" + item.CompletedTime + "||" + item.Props);
Console.WriteLine(item.UserId + "||" + item.LogName + "||" + item.TaskDisplayName + "||" + item.CompletedTime + "||" + item.Props);
}
}
//.Dump("Said Tasks Completed"); //using linqpad's Dump method, this just outputs the results to the display
}
}
//If you don't want completed tasks remove the second part in the where clause
private static List<EventRecord> GetCompletedScheduledTaskEventRecords(EventLogSession session, string scheduledTask)
{
const int TASK_COMPLETED_ID = 102;
var logquery = new EventLogQuery("Microsoft-Windows-TaskScheduler/Operational", PathType.LogName, "*[System/Level=4]") { Session = session };
return GetRecords(logquery,
x => x.Properties.Select(p => p.Value).Contains($@"\{scheduledTask}") && x.Id == TASK_COMPLETED_ID).ToList();
}
private static IEnumerable<EventRecord> GetRecords(EventLogQuery query, Func<EventRecord, bool> filter)
{
using (var reader = new EventLogReader(query))
{
for (var record = reader.ReadEvent(); null != record; record = reader.ReadEvent())
{
if (!filter(record)) continue;
yield return record;
}
}
}
}
}