banner



How To Create A Service From A Vb.net Program

Introduction

Yesterday I got a phone call from my brother, or really he sent me a message over MSN. He wanted to know if I could help him create a programme with a very specific requirement. Where he works they have a arrangement that creates a lock file when you enter a new periodical into the system. Nonetheless because of a bug (?) in that system, this file is not always deleted afterward the periodical accept been entered. If this file is non removed, no more journals tin be entered and the organization runs amok.

So my brother wanted a program that could monitor a binder for this file, if information technology'south non removed within a specified time, say 1 minute, an e-post notification is supposed to exist sent. Since this plan was supposed to run on the server, information technology needed to be a Windows Service.

Creating a Windows Service

Creating a Windows Service might non be something you do on a daily bases, during my career I've only made 3 or 4 of them, and this one was the very commencement I've created using .Net. Developing a Windows Service used to exist pretty darn difficult, but not any more. Every bit it turned out it's fairly easy these days.

You lot beginning by selecting the Windows Service project type in the New Projection dialog box in Visual Studio.

image

Doing that will give y'all a ServiceBase designer on which you lot tin drop your controls, but since a Service usually don't collaborate with the desktop, since information technology's supposed to be running even if nobody is logged in, you shouldn't utilise input controls such as text boxes or buttons. Using a Timer is a normal way of handling the work the service should practice, only in my example I but needed a FileSystemWatcher, so I merely dropped that on to the designer surface. The designer as well have a handful of properties, many of which are named Tin can… such as CanPauseAndContinue and CanStop. If you set the CanPauseAndContinue holding to True you can override the OnPaus and OnContinue methods. In my case I wasn't interested in that but I did desire an administrator to be able to end the service so I left the CanStop property as Truthful. If yous, like me, leave the properties with their default settings you volition have to override the OnStart and OnStop methods and I will cover that shortly.

I needed a way to store settings for this service, such as the time it would wait before sending an eastward-mail, the folder and file it was going to watch, and diverse SMTP and mail settings, such equally the subject and the body text. To go on it as simple as possible I decided to add together an App.Config file. To do that just right click on the project in the solution explorer and select Add > New Item, in the context menu. Find the Application Configuration template and click the Add together push. Note, exit the name as app.config Visual Studio will automatically rename this file and copy it to the Bin folder when you lot build the projection. To be able to read the config file y'all need to add a reference to Arrangement.Configuration.

I will not get into the details of using an app.config file but in short you need to add an <appSettings> department under the <configuration> node under which you add your own settings.

          <?          xml                    version          ="1.0"          encoding          ="utf-8"          ?> <          configuration          >   <          appSettings          >                                <          add                    key          ="emailSubject"          value          ="Tin somebody remove this file please?"          />     <!--                    more settings go here…                    -->                  

Y'all can then read these values using the ConfigurationManager.AppSettings() method (this requires that yous take imported the System.Configuration namespace which we ready a reference to before).

In my service I added a individual method which I simply chosen ReadSettings. I will non show y'all all of that code since it's mainly banality plate, but a function of it looks like this:

          Private Office          ReadSettings(ByRef          logMessage          As String)          Every bit Boolean   Dim          emailRecipients          As Cord()   _eMailTo =          New          List(Of String)          Try          emailRecipients = ConfigurationManager.AppSettings("emailTo").Split(";"c)          Take hold of          ex          Every bit          Exception     logMessage = _
"No e-mail recipients with valid due east-mails found, " & _
"
edit ""emailTo"" in the config file."
Return False Cease Try For Each electronic mail In emailRecipients email = email.Trim If Non String.IsNullOrEmpty(e-mail) AndAlso IsValidEmail(e-mail) Then _eMailTo.Add(email) Terminate If Next If _eMailTo.Count = 0 And then logMessage = "No electronic mail recipients with valid e-mails found." Return False End If Try _subject = ConfigurationManager.AppSettings("emailSubject") Grab ex Every bit Exception logMessage = "No electronic mail discipline found" _subject = String.Empty End Endeavour 'read the rest of the settings Render True End Function

This method takes a parameter, logMessage, by reference. In some cases, for example with the electronic mail subject, it is allowed to leave that out of the config file and the application volition but send the e-mail without a subject. Other settings, like the address or addresses to ship the due east-post to is required. The ReadSettings method will render Imitation if some required setting was non found, or in the incorrect format. The actual writing to the log is washed by the OnStart method, or rather information technology's done by another modest helper method that is called past the OnStart method.

          Private Sub          WriteLogMessage(ByVal          message          As String, _
ByVal blazon As EventLogEntryType) If Not EventLog.SourceExists("File Observer") And so EventLog.CreateEventSource("File Observer", "File Observer Log") End If Dim log As New EventLog() log.Source = "File Observer" log.WriteEntry(message, type) Cease Sub

I put all validation rules in the ReadSettings() method so that when it'south time to transport the e-post, I know that I accept east-post addresses that are valid (or rather, that they have a valid form, not that I tin check if the address itself really exists), and that the SMTP IP port is fix to a valid integer and then on.

The OnStart() and OnEnd() methods

Even though yous can override the constructor of the ServiceBase command, you shouldn't really put initialization code at that place. This is because if the service is stopped so restarted the constructor is not called over again, but the OnStart() method is. So initialization should go into that method.

In my very specific case, I used a FileSystemWatcher to monitor the specified folder for the creation of the specified file. If the ReadSettings() method returned True I started monitoring the folder. If not I needed a fashion to end the service from starting and write an error message to the effect viewer. Unfortunately the OnStart() method does not have a style of signaling an error, then what you need to practice is to phone call the SetServiceStatus() function which is a Win32 API part. Import the Arrangement.Runtime.InteropServices namespace and add the following code to your class.

<StructLayout(LayoutKind.Sequential)> _          Public Structure          SERVICE_STATUS          Public          serviceType          As Integer   Public          currentState          As Integer   Public          controlsAccepted          Equally Integer   Public          win32ExitCode          As Integer   Public          serviceSpecificExitCode          As Integer   Public          checkPoint          Equally Integer   Public          waitHint          As Integer End Structure  Public Enum          State   SERVICE_STOPPED = &H1   SERVICE_START_PENDING = &H2   SERVICE_STOP_PENDING = &H3   SERVICE_RUNNING = &H4   SERVICE_CONTINUE_PENDING = &H5   SERVICE_PAUSE_PENDING = &H6   SERVICE_PAUSED = &H7          End Enum                                        Private Declare Car Function          SetServiceStatus          Lib                    "ADVAPI32.DLL"          ( _          ByVal          hServiceStatus          Equally          IntPtr, _          ByRef          lpServiceStatus          Every bit          SERVICE_STATUS _ )          Equally Boolean
Private
_serviceStatus As SERVICE_STATUS

And so the following is the lawmaking I used in the OnStart() method.

          Protected Overrides Sub          OnStart(ByVal          args()          As Cord)          Dim          handle          As          IntPtr =          Me.ServiceHandle   _serviceStatus.currentState = Ready(State.SERVICE_START_PENDING)   SetServiceStatus(handle, _serviceStatus)          Dim          logMessage          As Cord          =          String.Empty          If Non          ReadSettings(logMessage)          Then          WriteLogMessage(logMessage, EventLogEntryType.Mistake)     _serviceStatus.currentState = Fix(State.SERVICE_STOPPED)     SetServiceStatus(handle, _serviceStatus)          Else     If Not String.IsNullOrEmpty(logMessage)          And then          WriteLogMessage(logMessage, EventLogEntryType.Information)          Terminate If                    'Start the file watching...                    With          FileSystemWatcher1       .BeginInit()       .Filter = _fileMask       .IncludeSubdirectories = _includeSubFolders       .Path = _folderName       .EnableRaisingEvents =          True          .EndInit()       _serviceStatus.currentState = Fix(State.SERVICE_RUNNING)       SetServiceStatus(handle, _serviceStatus)          End With   Terminate If Terminate Sub        

So if everything works out the manner information technology should I showtime the FileSystemWatcher by setting its EnableRaisingEvents property to Truthful. In the OnStop() method I simply fix this property to Fake to disable information technology.

When the FileSystemWatcher finds that the file that is being watched is created it raises the Created() event, in which I get-go a new thread that will but sleep for the specified number of seconds and so bank check if the file however exists. If it does information technology sends the email.

          Individual Sub          FileSystemWatcher1_Created( _          ByVal          sender          As Object, _          ByVal          e          Every bit          System.IO.FileSystemEventArgs)          Handles          FileSystemWatcher1.Created          If          e.ChangeType = IO.WatcherChangeTypes.Created          Then     Dim          thread          As New          Threading.Thread(AddressOf          WatchFile)     thread.Get-go(east.FullPath)          End If Cease Sub  Individual Sub          WatchFile(ByVal          fullPath          As Object)          Dim          fileName          Every bit String          =          CStr(fullPath)   Threading.Thread.Sleep(_delayTime * 1000)          If          IO.File.Exists(fileName)          And then          SendMail()          End If End Sub        
          Private Sub          SendMail()          Dim          mail          Equally New          System.Net.Mail service.MailMessage          For Each          electronic mail          In          _eMailTo     mail.To.Add together(New          Net.Postal service.MailAddress(e-mail))          Adjacent          postal service.From =          New          Cyberspace.Mail service.MailAddress(_emailFrom)   postal service.Subject = _subject   post.Trunk = _body          Dim          smtpClient          As New          Net.Mail service.SmtpClient(_smtpHost)          With          smtpClient     .Port = _smtpPort          If          _requireAuthentication          Then          .Credentials =          New          Cyberspace.NetworkCredential(_authenticateName, _
_authenticatePassword) Finish If Try .Send(mail) Catch ex As Exception WriteLogMessage("Unable to send post: " & ex.Message, _
EventLogEntryType.Error) End Try Stop With End Sub

Adding an installer to the project

Since this is a Windows Service it has to exist installed as such so that it's listed in the Service control panel applet. So you lot demand to add an installer to the project. Note that this installer is not the same thing as a setup program, it will just add the necessary code that allows this awarding to be installed as a service using the InstallUtil.exe command line tool that comes with the .Internet framework. More about that tool in a 2nd.

To add an installer select your ServiceBase designer and right click on its surface and select Add Installer in the context menu. This volition add a new Installer designer to your project that contains two component, a ServiceInstaller and a ServiceProcessInstaller.

Select the ServiceInstaller and change its DisplayName property. This will be the proper noun that is listed in the control console applet. You can also modify the StartType belongings to Automatic if you lot want your service to start directly after information technology has been installed. In my case I left that property as Transmission.

Now select the ServiceProcessInstaller and set the Account property to LocalSystem.

That'southward information technology. You tin now build the project. To do the installation open up a Visual Studio Command Prompt and type:

InstallUtil c:\thePath\theNameOfYourAssembly.exe

And presto! Your service should now be listed among the others in the Services command panel applet. Try to start and cease it from in that location. If y'all desire to uninstall the service, which yous must do if y'all need to make some changes to the source code, then type the following at the control prompt.

InstallUtil /u c:\thePath\theNameOfYourAssembly.exe

Determination

Even though this was a Windows Service with some very specific requirements I hope that this commodity have answered some questions on how you can create your own services.

Take fun!

Source: https://blogs.msmvps.com/joacim/2009/09/13/creating-a-windows-service-using-vb-net/

Posted by: morriscouttepore1968.blogspot.com

0 Response to "How To Create A Service From A Vb.net Program"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel