ARTICLE

A Scheduled Application Launcher Service in VB.NET

Posted by Mike Gold Articles | Visual Basic 2010 October 06, 2004
This an article is on launching scheduled tasks. Not quite as exciting as launching a spaceship into outer space, but…hey, even astronauts have to automate some of their day to day activities.
Download Files:
 
Reader Level:

Well we've entered a new era folks! The government isn't the only one who can make a spacecraft and launch it into space. In honor of the historical space mission by Mike Melvill, first civilian astronaut, I've decided to write an article on launching, well... scheduled tasks. Not quite as exciting as launching a spaceship into outer space, but... hey, even astronauts have to automate some of their day to day activities.

Although Microsoft already includes a task scheduler in the operating system, I thought it would be an interesting exercise to create one that runs processes read out of an xml file. This task scheduler did not have to be all things to all people. I simply needed it to start a process at a certain time of day everyday. Specifically, I need it to start and stop windows services using the two batch files listed below:

Start.bat Stop.bat
net start MyService net stop MyService

Table 1 - Using Batch files to stop and start Windows Services

The UML design for the Schedule Launcher (reverse engineered with WithClass) is shown below in figure 2. The design consists of the Service1 class that is automatically generated by the framework. The Service class contains a Threading.Timer which is used to poll the system clock for the current time in order to check for a possible launch. Also in the design is a singleton ProcessReader class that reads the processes and times out of an xml file.

Figure 2 - UML Diagram of the Windows Service for Launching Scheduled Tasks

The timer class allows us to intercept an event every 30 seconds that the service is active. The timer is constructed with the callback delegate for the event handler along with the time we want the timer to trigger an event. Initially we set the time to infinite in order to keep the timer stopped.
 
Listing 1 - Constructor of Service containing timer construction

Public Sub Service1()
' This call is required by the Windows.Forms Component Designer.
InitializeComponent()
' Read process and launch times from the xml file
ReadProcesses()
' set up the timer in the stopped state
_timer = New Timer(New TimerCallback(AddressOf OnNextMinute), Nothing, Timeout.Infinite, Timeout.Infinite)
End Sub

When we are ready to start the timer, we simply change the time period from infinite to a finite period in milliseconds:

Listing 2 - Starting the Timer

Private Const TIMER_INTERVAL As Long = 30000L
Private Sub StartTimer()
' set the timer to trigger an event every 30 seconds
_timer.Change(0, TIMER_INTERVAL)
End Sub

Once we've started the timer we need to check it against the system clock to see if we are ready to launch our process. The OnNextMinute event handler is triggered every 30 seconds by the timer and compares the system clock against the file time in the xml file corresponding to the process. If the time is within 1 minute, it launches the process.

Listing 3 - Event Handler triggered by the timer every 30 seconds

Public Sub OnNextMinute(ByVal state As Object)
' get the current system clock time
Dim currentTime As DateTime = DateTime.Now
' loop through each process data read from the XML file
For Each p As ProcessInfo In _processes
If (currentTime.Hour = p.StartTime.Hour) AndAlso (currentTime.Minute = p.StartTime.Minute) AndAlso p.Started = False Then
' minute reached, start the process
Dim path As String = p.Path & "\" & p.File
System.Diagnostics.Process.Start(path)
p.Started =
True
End
If
' reset process flag two minutes later, to be safe
If (currentTime.Hour = p.StartTime.Hour) AndAlso (currentTime.Minute > p.StartTime.Minute + 2) AndAlso p.Started = True Then
p.Started = False
End
If
Next p ' end for each process info
End Sub

Parsing Xml with XPath
 
Using an XmlDocument with XPath is a very convenient way for us to get the process information out of our file. Our Xml file consists of a set of processes containing the file to execute, the path, and the time to execute in each process node.
 
Listing 4 - Xml File containing Processes to Launch

<?xml version="1.0" encoding="utf-8" ?>
<Processes>
<Process>
<
Path>C:\workspace\QuotingService\bin\bin</Path>
<
File>start.bat</File>
<
Time>9:20 AM</Time>
</
Process>
<Process>
<
Path>C:\workspace\QuotingService\bin\bin</Path>
<
File>stop.bat</File>
<
Time> 4:15 PM </Time>
</
Process>
<Process>
<
Path>C:\CommodityService\bin</Path>
<
File>start.bat</File>
<
Time>9:20 AM</Time>
</
Process>
<Process>
<
Path>C:\CommodityService\bin</Path>
<
File>stop.bat</File>
<
Time> 4:15 PM </Time>
</
Process>
</Processes>

Below is the routine in the ProcessReader that reads the process nodes into an array of ProcessInfo classes. The constructor loads in the Xml file by calling Load on the XmlDocument. The GetProcesses method selects all the process nodes via XPath. The XPath query //Processes/* asks for all of the nodes underneath the Processes node. The double slash tells SelectNodes to skip past all the ancestor nodes and go right to the Processes node. The star (*) tells xpath to choose all of the nodes underneath Processes.
 
Listing 5 - Reading the Process Nodes using XPath and XmlDocument

Private _xDoc As XmlDocument = Nothing
Public Sub ProcessReader()
Dim path As String = GetConfigPath()
_xDoc =
New XmlDocument()
_xDoc.Load(path)
' Load the xml file
End Sub
Public
Function GetProcesses() As ProcessInfo()
' XPath statement for selecting nodes
Dim xpath As String = "//Processes/*"
' Select the nodes with the XPath query
Dim nodes As XmlNodeList = _xDoc.SelectNodes(xpath)
' Create an array to hold process info
Dim processes As ProcessInfo() = CType(Array.CreateInstance(Type.GetType("ApplicationLauncherService.ProcessInfo"), nodes.Count), ProcessInfo())
' Go through each process node and populate process
' info object
Dim i As Integer = 0
For Each node As XmlNode In nodes
Dim p As ProcessInfo = New ProcessInfo(node("Path").InnerText, node("File").InnerText, node("Time").InnerText, "")
processes(i) = p
i += 1
Next node
Return processes
End Function

Below is the ProcessInfo class used to contain the process launch information that we read with our GetProcesses method. It is a simple class containing only fields to hold the process info and times to launch along with a constructor. This class also converts our time string to a DateTime. We are only interested in the time here, so we concatenate a date onto the string in order to produce a legitimate DateTime with the Convert class.
 
Listing 6 - Reading Process info class 

Public Class ProcessInfo
Public Path As String ' path of the process file
Public File As String ' name of the application
Public Arguements As String ' arguments of the app
Public Started As Boolean ' whether or not it was already started
Public StartTime As DateTime
Public Sub New(ByVal path_Renamed As String, ByVal file_Renamed As String, ByVal starttime_Renamed As String, ByVal arguments As String)
Path = path_Renamed
File = file_Renamed
StartTime = Convert.ToDateTime(" 11/17/1965 " & starttime_Renamed)
Arguements = arguments
Started =
False
End
Sub
End
Class

Conclusion

The time for civilian space travel may be here sooner than we know it. In the meantime, while I'm waiting for my lunar flight, I'll continue to hang out in my namespace and experiment with .NET. Happy Launching!

NOTE: THIS ARTICLE IS CONVERTED FROM C# TO VB.NET USING A CONVERSION TOOL. ORIGINAL ARTICLE CAN BE FOUND ON C# CORNER (WWW.C-SHARPCORNER.COM).

share this article :
post comment
 

Hii,

how can i make a windows based service in c#.net to start an  application's EXE whenever my system boots.

It's working with a normal Windows Application but the same code does not seem to launch the exe from a Windows Application.

Thanks,

Subir

 

 

Posted by Subir Sen Oct 11, 2006

hello sir ,

i want to make a service that will start my application's EXE whenever the system boots.

Posted by Ankit Phophalia Jul 17, 2006

hello sir,

how can i make a windows based service in c#.net to start my application's EXE whenever my system boots.

Posted by Ankit Phophalia Jul 17, 2006

hi

iam having an exe file,i want to make it as service,for that i am looking to write a windows service to execute that exe.

how can i start executing that exe by creating a windows service using vb.net.

 

please help me in this.

Posted by Raja yashwanth reddy Gunda May 17, 2006
Become a Sponsor
PREMIUM SPONSORS
  • Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
Become a Sponsor