In addition to Garth's answer, you can also use the Windows Task Scheduler to create and execute tasks on remote computers, see:
Schtasks.exe - Win32 apps | Microsoft Docs[
^]
Personally I prefer to call the Windows Task Scheduler with Process.Start() as I find the existing libraries too complex and also think problems can arise when things change after a Windows update.
Here is a example for local usage:
private void CreateSchedulerTask(string scheduleTime)
{
var command = Path.Combine(Environment.SystemDirectory, @"SchTasks");
var args = "/Query";
var result = Utilities.ProcessRun(command, args, true);
if (result.Contains("MyTaskName"))
{
Debug.Print("MyTaskName already running.");
return;
}
command = Path.Combine(Environment.SystemDirectory, @"SchTasks");
args = "/Create /SC WEEKLY /D MON /TN \"MyTaskName\" /TR \"" + Application.ExecutablePath + "\" /ST " + scheduleTime;
Debug.Print(command + " " + args);
result = Utilities.ProcessRun(command, args, false);
}
public static string ProcessRun(string fileName, string args, bool redirectStandardOutput, bool waitForExit = true, bool hideWindow = false)
{
string result = string.Empty;
const int ErrorCancelled = 1223;
try
{
using (Process process = new Process())
{
process.StartInfo = new ProcessStartInfo();
process.StartInfo.FileName = fileName;
if (hideWindow)
{
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
}
if (!string.IsNullOrEmpty(args))
{
process.StartInfo.Arguments = args;
}
process.StartInfo.CreateNoWindow = true;
if (redirectStandardOutput)
{
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.Start();
using (StreamReader reader = process.StandardOutput)
{
string resultOut = reader.ReadToEnd();
Debug.Print(resultOut);
}
}
else
{
process.StartInfo.Verb = "runas";
process.StartInfo.UseShellExecute = true;
process.Start();
}
if (waitForExit)
{
process.WaitForExit(120000);
}
}
}
catch (Win32Exception ex)
{
if (ex.NativeErrorCode == ErrorCancelled)
{
result = "ProcessRun() cancelled";
}
else
{
result = @"ProcessRun() error: " + ex.Message;
}
}
catch (Exception ex)
{
result = @"ProcessRun() error: " + ex.Message;
}
return result;
}