I thought that creating a simple system service under VB .NET would be a piece of cake. Boy, was I wrong. First, I find general postings through Google that say you should use the Windows.Forms.Timer. Then, I found conflicting information that says you have to derive the timer from a timer class through code to make it work. Then, people are reporting all sorts of trouble using the various types of threads available. I can't debug threads using the VS 2010 Just-in-Time debugger for obvious reasons (although, I don't know if there is an alternate method to doing this). Wow, how confusing all this is when there is no definitive guide...
My project is an application launcher (similar to cron) that will fire off periodically within a certain amount of seconds. I am trying to use the Process.Start() method. I have a Beep() function as the first instruction, and the Process.Start, along with a Process.WaitForExit method to make it block as the last instruction. I had my code doing this through timers, but now I am starting to use threads. No difference in execution. The over-ridden OnStart method does kick off (as I am certain through debugging), but nothing ever happens when starting the service in production, as if it were ignoring all my code. Putting loops and logic in the OnStart method yields a process that won't start. I know it is a threading issue, but I also know it must be mandatory to use threads. I am now dumbfounded as to how to make this work. I am curious to know the solution.
In addition to the service class, I have a ServiceInstaller and ProcessInstaller implemented that I copied verbatim from MSDN.
Here is some of the code I am trying to work with. Note that this simply reflects the current state of my code in trying to implement the logic within a thread instead of a timer (which to me would be optimal):
Dim config As String
Dim configValues(2) As String
Dim objReader As System.IO.StreamReader
Dim interval As Integer
Dim launchProcess As Process
While True
Beep()
' This sub runs every time the elapsed milli-seconds of the timer pass
' Sp add your code here.
config = "30 c:\WiFiDropOutFix\start.vbs"
Try
objReader = New System.IO.StreamReader("C:\WiFiDropOutFix\config.txt")
config = objReader.ReadToEnd
objReader.Close()
Catch ex As Exception
End Try
configValues = config.Split(New Char() {" "c})
interval = Convert.ToInt32(configValues(0))
If Not interval > 0 And Not interval < 61 Then
interval = 10
End If
launchProcess = Process.Start(configValues(1))
launchProcess.WaitForExit()
Thread.Sleep(interval * 1000)
End While
End Sub
Here is my OnStart Code by Request:
Protected Overrides Sub OnStart(ByVal args() As String)
appLaunchLogicThread = New Thread(AddressOf appLaunchLogic)
appLaunchLogicThread.Start()
End Sub
TIA.
OnStart
code. I think you are going to have to instrument your code with logging information verbose enough to provide clues as to why this isn't working in production - Brian Gideon 2012-04-05 19:50
Process.Start
to throw an exception which will terminate the thread. Put a try-catch around all of your code and log all exceptions to a file - Brian Gideon 2012-04-05 19:52
Try going to the Service control panel, Editing the properties on your service, and checking the option that says either "Interactive Service" or "Allow Service to Interact With the Desktop". If you are trying to fire up a new process and see it on the screen, nothing will happen unless this option is enabled.
Also, set the logon credentials of the service to Administrator to ensure it is not a permissions problem. If it works, you have discovered the issue.
One other tip: Write all the processing code as a normal app which you can easily debug, and once all the bugs are ironed out and you know the code is flawless, then implement it as a service.
Ok, I have managed to find something of a reason behind why my project wasn't working. I do recall seeing someone say that the [STAThread] directive was necessary for launched processes to execute within a service, and it had to be placed right before the Main function. Codeproject has issued a cron project for Windows Services in C#, and it uses this directive. I will have to look at this issued project more, but perhaps it can't be implemented in VB .NET. At this point, I do not understand how to incorporate a service launcher through a Main function / class through the VB .NET Visual Studio Service template, since it seems to launch itself by itself already.
Also, I have finally managed to find a Windows cron service program that will work within seconds that doesn't have a mandatory commercial license, can be used for free, and has an affordable registration (from what is indicated on the Website). It is called WinCron.
OnStart
code - Brian Gideon 2012-04-05 19:12