Random Task Scheduler Console Application

Here is the scenario: Your boss asks for a program to be scheduled at a random time every day of the week. In your proactive mindset, a program will be designed to schedule any program to be executed either daily or weekly. And now we get to use our tools and ingenuity to create that solution.

Let’s create our new project after starting our favorite version of Visual Studio. In this case, we are using Community Edition of Visual Studio 2019 version 16.9.2

We will be creating a .Net Framework console app, as shown to the left. After typing in the project name, you should be able to leave the remaining selections at default. Click Create.

Now you will be presented with an empty Main(string[] args) method. Place the code shown below inside of that method.

if ((args[0] == "-h" || args[0] == "?") || args.Count() < 3)
{
    Console.WriteLine("RandomTaskScheduler usage:");
    Console.WriteLine("RandomTaskScheduler [? -h]");
    Console.WriteLine("RandomTaskScheduler [-d -w] TaskName \"c:\\temp\\test.bat\"");
    Console.WriteLine("   ? = display this help screen");
    Console.WriteLine("   -h = display this help screen");
    Console.WriteLine("   -d creates daily task while -w will be once per week");
    Console.WriteLine("   Taskname is the name that will show in your task scheduler");
    Console.WriteLine("   Path and filename will be the final parameter, placed in quotes");
}
else
{
    if (args[0] == "-d")
    {
        int hr, min;
        string taskname = args[1];
        string fname = args[2];
        System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
        proc.FileName = "cmd.exe";
        hr = RandInt.Random(6, 15);
        min = RandInt.Random(1, 59);
        string strCommand = "/c schtasks /create /sc once /tn " + taskname + " /ST " + hr.ToString("00") + ":" + min.ToString("00");
        strCommand = strCommand + " /tr " + fname;
        proc.Arguments = strCommand;
        System.Diagnostics.Process.Start(proc);
    }
    else if (args[0] == "-w")
    {
        int day;
        string taskname = args[1];
        string fname = args[2];
        System.Diagnostics.ProcessStartInfo proc = new System.Diagnostics.ProcessStartInfo();
        proc.FileName = "cmd.exe";
        day = RandInt.Random(1, 5);
        string stdate = DateTime.Now.AddDays(day).ToString("MM/dd/yyyy");
        string strCommand = "/c schtasks /create /sc once /tn " + taskname + " /SD " + stdate + " /ST 18:00";
        strCommand = strCommand + @" /tr " + fname;
        proc.Arguments = strCommand;
        System.Diagnostics.Process.Start(proc);
    }
}

Below the Main() method, insert the RandInit class that it references

public static class RandInt
{
    private static Random rand;
    private static void Init()
    {
        if (rand == null) rand = new Random();
    }
    public static int Random(int min, int max)
    {
        Init();
        return rand.Next(min, max);
     }
}

What does all of this code mean? In the first IF block, we are checking to see if “?” or “-h” were entered as the first argument. We are also checking to see if less than three arguments were entered. In either of these cases, the usage help will be displayed.

After determining that we have entered three arguments after the RandomTaskScheduler command name, we check to see if the first argument is “-d” or “-w.” If that is not the case, nothing is scheduled since the next two IF statements are false.

With a daily (-d) random schedule being created, we will randomly select and hour and minute using the RandInt class shown above. Weekly (-w) will select a random day and schedule the task for that number of days from today.

Taskname and filename are loaded from args 1 and 2. We set up a new process (proc) and assign it to the cmd.exe filename. Next, we will create the command string to schedule a task once with a start time (for daily) or a start date and specific time. Add the filename to command string, set the process argument to command string, and start it.

Additional challenges to your coding skills:

  1. Create another argument allowing entry of the time for weekly execution
  2. Create a monthly option which will select from the next 28/30/31 days and even exclude weekends from the schedule
  3. Investigate additional schtasks options and allow some of those to be specified in args

See also: Microsoft – schtasks commands

Leave a Reply

Your email address will not be published. Required fields are marked *