I've been working on creating a windows service that receives a JSON result from an API. It then takes that data, deserializes it into a list of objects. Then uses information from those objects to send an email.
So far i've been writing and testing using it like a console application via a method described here: https://social.technet.microsoft.com/wiki/contents/articles/30957.c-windows-service-in-console-mode-for-debug-and-admin.aspx
This worked really well and the service accomplished everything I wanted it to do. Now it was time to build it into a true service and install on my machine and test it that way.
The solution builds just fine and the installer works as well. Once installed, if I try to start the service I am met with Error: 1053 and the service is stuck as "Starting". I then have to uninstall and restart the computer to make any changes and build again to test.
So far I have tried:
My OnStart:
//prints function we are in to the debug console and sets the service
//status, as well as adds an entry to the event log
Debug.WriteLine("In OnStart.");
ServiceStatus serviceStatus = new ServiceStatus();
serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING;
serviceStatus.dwWaitHint = 100000;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
//eventLog1.WriteEntry("In OnStart.", EventLogEntryType.Information);
Thread t = new Thread(new ThreadStart(MainRunner));
t.Start();
// Update the service state to Running.
serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING;
SetServiceStatus(this.ServiceHandle, ref serviceStatus);
MainRunner():
//timer used for evaluating every hour from start time
System.Timers.Timer timer = new System.Timers.Timer();
timer.Elapsed += new ElapsedEventHandler(this.OnTimer1);
timer.Interval = /*3600000;*/ 60000;// for 1 minute testing
//starts the timer
timer.Start();
DateTime hour = new DateTime(1, 1, 1, 17, 0, 0);
//checks faulty vehicles for the day, everyday at 5pm
while (true) //infinite loop
{
//gets the current DateTime
DateTime Now = DateTime.Now;
//verifies that the current DateTime is 5pm and not a Saturday or Sunday
if (Now.Hour == hour.Hour && Now.Minute == hour.Minute && Now.Second == hour.Second
&& Convert.ToInt32(Now.DayOfWeek) != 0 && Convert.ToInt32(Now.DayOfWeek) != 6)
{
TwenFourHour(); //calls the daily check
//prints to debugger that daily check is done
Debug.WriteLine("Out of TwenFourHour");
//eventLog1.WriteEntry("Out of TwenFourHour", EventLogEntryType.Information);
}
}
SetServiceStatus():
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool SetServiceStatus(System.IntPtr handl, ref ServiceStatus serviceStatus);
This comes directly from Microsoft here: https://learn.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer?redirectedfrom=MSDN
I'm sure there are better ways to do what im doing in here (like a scheduled task, but it's not what was asked of me) but it's what I came up with. Essentially I need to access one GET response from the API every hour. This does not send an email. I also need to access a separate GET response every day at 5pm, this sends an email. I needed to exclude weekends from this as well. Weekends for the hourly check are handled in the timer's method.
I figured out the issue.
It's with the while loop. I'm surprised as I saw this mentioned as a method of time checking within a service in a few posts here but I guess it's very unhappy with it.
What i've done instead is now run a timer every minute. The timer then checks against the hour and minute (ignoring seconds, since the timer could be started anywhere from 0-59). This way it's bound to tick once anywhere within 5pm.