Long Story short I built a console application that worked just fine, then was told that it needed to be a windows service. So I constructed a windows service project pretty much following Microsoft's recommendations and the service runs and starts and stops fine but it doesn't start the application that I converted from a console app to the service. I'm having trouble understanding why.
Question: How do you start a long running process using a windows service? Can windows services not utilize code in class library's?
public partial class CallQService : ServiceBase
{
private static System.Threading.Timer _timer;
private static CallQ _callQ;
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool SetServiceStatus(IntPtr handle, ref ServiceStatus serviceStatus);
public CallQService(string[] args)
{
// Update the service state to Start Pending.
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(ServiceHandle, ref serviceStatus);
InitializeComponent();
string eventSourceName = "MySource";
string logName = "MyNewLog";
if (args.Any())
{
eventSourceName = args[0];
}
if (args.Length > 1)
{
logName = args[1];
}
eventLog1 = new EventLog();
if (!SourceExists(eventSourceName))
{
CreateEventSource(eventSourceName, logName);
}
eventLog1.Source = eventSourceName;
eventLog1.Log = logName;
// Update the service state to Running.
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(ServiceHandle, ref serviceStatus);
}
protected override void OnStart(string[] args)
{
Debugger.Launch();
eventLog1.WriteEntry("The Service Has Started");
System.Timers.Timer timer = new System.Timers.Timer
{
Interval = 60000 // 60 seconds
};
timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Start();
//This is where the process starts that is supposed to run my application and generate my data. It does not do that at all. it hits this and runs through the code in this class file, but once it is supposed to move into code in one of my class library's it just stops and doesn't do anything else.
Initialize();
}
private void OnTimer(object sender, ElapsedEventArgs e)
{
// TODO: Insert monitoring activities here.
eventLog1.WriteEntry("Monitoring the System", EventLogEntryType.Information);
}
protected override void OnContinue()
{
eventLog1.WriteEntry("In OnContinue.");
// Update the service state to Running.
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = ServiceState.SERVICE_CONTINUE_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(ServiceHandle, ref serviceStatus);
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
}
protected override void OnPause()
{
// Update the service state to Start Pending.
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = ServiceState.SERVICE_PAUSE_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(ServiceHandle, ref serviceStatus);
eventLog1.WriteEntry("The Service has Stopped.");
// Update the service state to Running.
serviceStatus.dwCurrentState = ServiceState.SERVICE_PAUSED;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
}
protected override void OnStop()
{
// Update the service state to Start Pending.
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = ServiceState.SERVICE_STOP_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(ServiceHandle, ref serviceStatus);
eventLog1.WriteEntry("The Service has Stopped.");
// Update the service state to Running.
serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
}
public static void Initialize()
{
var callDataRepo = CreateCallDataRepo();
var skillsRepo = CreateSkillsRepo();
_callQ = new CallQ(skillsRepo, callDataRepo);
_callQ.Start();
SetUpTimer(new TimeSpan(06, 46, 00));
}
private static ISkillsRepo CreateSkillsRepo()
{
// Generates an instance of Config data for pulling down skills from OADB database
ISkillsDataRepoConfig skillDataRepoConfig = new SkillsDataRepoConfig();
// generates an instance of skills repo and pulling in call data repo OADB databse config
ISkillsRepo skillsRepo = new SkillsRepo(skillDataRepoConfig);
return skillsRepo;
}
private static ICallDataRepo CreateCallDataRepo()
{
// Generates an instance of Config data for pulling down skills from OADB database
ICallDataRepoConfig callDataRepoConfig = new CallDataRepoConfig();
// generates an instance of call data repo and pulling in call data repo OADB databse config
ICallDataRepo callDataRepo = new CallDataRepo(callDataRepoConfig);
return callDataRepo;
}
private static void SetUpTimer(TimeSpan alertTime)
{
DateTime current = DateTime.Now;
TimeSpan timeToGo = alertTime - current.TimeOfDay;
if (timeToGo < TimeSpan.Zero)
{
return;//time already passed
}
_timer = new System.Threading.Timer(x =>
{
_callQ.StopGenerators();
_callQ.Start();
}, null, timeToGo, Timeout.InfiniteTimeSpan);
}
}