views:

124

answers:

3

I have been task with (ha) creating an application that will allow the users to schedule a command line app we have with a parameter.

So the command line app takes an xml and "runs it"

So bottom line I either need to create a windows service or learn how to interact with the Task Scheduler service already running on the box (version 1 Xp /2003)

At first I though it would be easy have a service run and when a job is submitted, calculate the time between now and run and set up a timer to wait that amount of time. This is better then checking every minute if it's time to run.

Were I hit a wall is I relized I do not know how to communicate with a running windows service. Except maybe create a file with details and have the service with a file watcher to load the file and modify the schedule.

So the underlying questions are how can I execute this psedo code

from client

 serviceThatIsRunning.Add(Job)

Or ineracting with the task schedule or creating .job files using c# 3.5

Edit:

To clarify I created a small sample to get my thoughts on "paper"

So I have a Job Class

public class Job
{
    #region Properties
    public string JobName { get; set; }
    public string JobXML { get; set; }
    private Timer _JobTimer;
    public Timer JobTimer
    {
        get
        {
            return _JobTimer;
        }
    }

    #endregion

    public void SetJobTimer(TimeSpan time)
    {
        if (_JobTimer != null)
        {
            _JobTimer.Dispose();
        }

        _JobTimer = new Timer(new TimerCallback(RunJob), null, time, time);

    }

    private void RunJob(Object state)
    {
        System.Diagnostics.Debug.WriteLine(String.Format("The {0} Job would have ran with file {1}", JobName, JobXML));
    }

    public override string ToString()
    {
        return JobName;
    }

    public void StopTimer()
    {
        _JobTimer.Dispose();
    }
}

Now I need to create an App to house these Jobs that is constantly running, that is why I though of Windows Services, and then a Windows app to allow the user to work with the Job List.

So the question is if I create a Windows Service how do I interact with methods in that service so I can change the JobList, add, delete, change.

Here is a small windows app I created to show that the Job class does run. Interesting point, If I am doing this correctly, I do not add the Job to a listbox and the Add method exits the Job Timer portion still runs and does not get picked up by the Garbage Collector.

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void btnAddJob_Click(object sender, EventArgs e)
    {
        Job job = new Job();

        job.JobName = txtJobName.Text;
        job.JobXML = txtJobXML.Text;
        job.SetJobTimer(new TimeSpan(0, 0, Convert.ToInt32(JobTime.Value)));

        // ??Even If I don't add the Job to a list or ListBox it seems 
        // ??to stay alive and not picked up by the GC            
        listBox1.Items.Add(job);
    }

    private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
    {
        if (listBox1.SelectedIndex > -1)
        {
            Job job = listBox1.Items[listBox1.SelectedIndex] as Job;

            txtJobName.Text = job.JobName;
            txtJobXML.Text = job.JobXML;
        }

    }

    private void btnRemove_Click(object sender, EventArgs e)
    {
        Job job = listBox1.Items[listBox1.SelectedIndex] as Job;
        job.StopTimer();
        listBox1.Items.Remove(job);
    }

    private void btnCollect_Click(object sender, EventArgs e)
    {
        GC.Collect();
    }
}
+1  A: 

If you want to schedule a task using the task scheduler it could be as simple as below. You just need to customize the command line arguments that you pass to schtasks for your needs. See this link for a detailed explanation of command line arguments.

Process p = Process.Start("schtasks", commandArgs);
p.WaitForExit();
Taylor Leese
A: 

If you want to start multiple tasks that run at different time intervals, you can create for instance a class JobThread that defines a timer that is initialized using the Initialize method:

m_timer = new Timer(new TimerCallback(this.timerHandler), null, this.Interval, this.Interval);

Furthermore, this class defines a List of Job objects. These jobs are executed from the timerHandler.

Finally, you create a singleton JobManager class that defines a Start and Stop method. In the Start method you do something like this:

        foreach (var jobThread in this.m_jobThreads)
        {
            jobThread.Initialize();
        }

This JobManager has also a Initiliaze method that accepts a XmlNode parameter. This method will parse the Xml-job you pass from the command-line.

Sander Pham
Why not use the built in scheduled task manager of windows (i.e. schtasks) to manage this?
Taylor Leese
Is also possible, but in case you have jobs running at different time intervals, you will still need a Timer mechanism. Or, different scheduled tasks.
Sander Pham
A: 

There was an answer on this thread that is no longer there but, I am going to try to create a listener by keeping a port open

WCF through Windows Services http://msdn.microsoft.com/en-us/library/ms733069.aspx

Also adding the attribute

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

Helps to keep state of the service.

Mike