Search code examples
c#windows-servicesquartz.netproduction

Windows service does nothing on production PC


I have an application that schedules jobs using Quartz.Net. It works on my development laptop perfectly both as a winforms application (with start and stop buttons) and as a Windows Services whose OnStart() and OnStop() event code matches the start and stop button code of the winforms application. They're both in the same solution using the same "model" code (in its own project).

If I run the winforms application on the production computer it works perfectly, the jobs are executed according to their schedule as expected. However if I install and run it as a Windows Service on the production PC nothing happens! The jobs do not run.

I have no idea how to debug this. Please let me know if you have any suggestions as to what might be wrong.

Also please let me know what other information I should be providing.

Oh - dev PC is running Windows 7, production PC is running Windows 8.1! Could that be the problem? I built the service by following this tutorial: http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx which does not indicate that anything special needs to be done for deploying to Windows 8?

Could this have something to do with environment variables (which I know nothing about)?

Here is some code which may be relevant:

The service:

namespace DataPump
{
    public partial class DataPumpService : ServiceBase
    { 

        private TaskManager _taskManager;

        public DataPumpService()
        {
            InitializeComponent();
            _taskManager = new TaskManager();
        }

        protected override void OnStart(string[] args)
        {
            _taskManager.Go();
        }

        protected override void OnStop()
        {
            _taskManager.Stop();
        }
    }
}

The form code (different project):

namespace DataPump
{
    public partial class Form1 : Form
    {
        private TaskManager _taskManager = new TaskManager();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            _taskManager.Go(); //Loops infinitely, does not block
            label1.Text = "Running...";
        }

        private void button2_Click(object sender, EventArgs e)
        {
            label1.Text = "Stopping...";
            _taskManager.Stop();
            label1.Text = "Idle";
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            _taskManager.Stop();
        }
    }
}

Selected code from TaskManager code (third project which the first two each reference):

public class TaskManager
{
    //...
    private IScheduler _scheduler = StdSchedulerFactory.GetDefaultScheduler();
    //...

    public void Go()
    {
        if (_scheduler.GetCurrentlyExecutingJobs().Count() == 0)
        {
            _scheduler.Start();
            _scheduler.AddCalendar(CalendarName, MakeSAPublicHolidayCalendar(), false, true);

            foreach (DatapumpJob job in JobList)
            {
                _scheduler.ScheduleJob(MakeJob(job), MakeTriggerCron(job));
            }
        }
    }

    //...

    public void Stop()
    {
        foreach (string name in _scheduler.GetCurrentlyExecutingJobs().Select(j => j.JobDetail.Key.Name))
        {
            _scheduler.Interrupt(new JobKey(name));
        }
        _scheduler.Shutdown(true);
    }
    //...
}

Where JobList is a get only property that generates a List<DatapumpJob>where DatapumpJob implements IInterrutableJob but adds common features including a job name which gets use by the three methods beginning Make... which are all private methods within the TaskManager class.


This code is to answer a question from the comments regarding ServiceBase.Run():

Program.cs (auto-generated):

namespace DataPump
{
    static class Program
    {
    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    static void Main()
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] 
        { 
            new DataPumpService() 
        };
        ServiceBase.Run(ServicesToRun);
    }
}

}


Solution

  • This turned out to be a network permissions issue. The service was running, it was just unable to access the network drive. So really my question was mi-specified.

    After trying this: https://serverfault.com/questions/177139/windows-service-cant-access-network-share we eventually got it to work by setting the service to run as a specific user account on the PC.