Console application -> Windows Service vb.net

MrFawlty
MrFawlty used Ask the Experts™
on
Hi,

I have a console application that needs to rebuilt as a windows service but I keep getting errors. Can someone help me by showing me the shell of a windows service? Code that allows me to simply add in the code doing the work it needs to do every x seconds?

I have been googling and trying multiple tutorials but nothing clear and succesful has been found, could someone with some experience with this help me out by providing a working shell?

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Create a new project of type C# windows service.  Open the designer for the service.cs file and then click the "click here to view code".  You'll see a method called OnStart.  This gets called when the service starts.  If your code is a short one time thing (unlikely) you would put that code here.  More likely, you want OnStart to start a System.Threading.Timer, and that timer than calls the code you were using in your console app.  The main trick is to remember this is going to be multithreaded, though you can easily avoid trouble by either having autoreset on the timer false and then turning it back on after each processing, or use a logical guard variable or some other sync method to avoid multiple concurrent calls.

Author

Commented:
Hi,

I subscribe to a newmailevent in DoNextExecution and when it's raised I want to process the new mails with ProcessMail. I get a FileNotFoundException in Main() atm, I really really need to get this to work.

How can I fix this?


Public Class Service1

    Private _DocumentLoaded As Boolean
    Private _recRE As …
    Private _tmrTimer As Timers.Timer
    Private _nwcCredential As …
    Private _objService As …

    Protected Overrides Sub OnStart(ByVal args() As String)
        _tmrTimer = New Timers.Timer
        With (_tmrTimer)
            .Enabled = True
            .Interval = 60000
            .AutoReset = True
        End With
        AddHandler _tmrTimer.Elapsed, AddressOf _tmrTimer_Tick

        _tmrTimer.Start()

    End Sub

    Private Sub ProcessMail(ByVal objService As Service)
        SyncLock Me
            Try
                _tmrTimer.Stop()
                Dim itemShape As New ItemShape(ShapeType.Id)
                Dim inboxItems As FindItemResponse = objService.FindItem(StandardFolder.Inbox, itemShape)
                For i As Integer = 0 To inboxItems.Items.Count - 1
                    ‘get all emails and process them (SQL DB)

            Catch ex As ServiceRequestException
                Console.WriteLine("Error: " + ex.Message)
                Console.WriteLine("Error: " + ex.XmlMessage)
                Console.Read()
            Catch ex As WebException
                Console.WriteLine("Error: " + ex.Message)
                Console.Read()
            Finally
                _tmrTimer.Start()
            End Try
        End SyncLock
    End Sub

    Public Function LoadMHTDocument(ByVal Path As String) As Boolean
‘Loads the MHT file
    End Function

    Private Shared Function DeterminePriority(ByVal objImportance As Importance) As eRITSPriority
        Select Case objImportance
            Case Importance.None
                Return eRITSPriority.Unknown
            Case Importance.Low
                Return eRITSPriority.Low
            Case Importance.Normal
                Return eRITSPriority.Medium
            Case Importance.High
                Return eRITSPriority.High
            Case Else
                Return eRITSPriority.Unknown
        End Select
    End Function

    Protected Overrides Sub OnStop()
    End Sub

    Private Sub _tmrTimer_Tick(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs)
        DoNextExecution()
    End Sub

    Private Sub DoNextExecution()
‘listen for new mails, if there’s a new mail then fire ProcessMail(_objService)

    End Sub

End Class

Open in new window

Top Expert 2010

Commented:
Since your diving into this for the first time it's going to be more complicated for you to understand. You will need not only an explanation but some in depth walkthrough. You will also want to add an "Installer" to that project, then you will need to change the settings of your service to run under the context you desire (LocalSystem) being the most common. You also want to change how the service is started whether automatically or manual. Then your going to need to know how to install/remove the service for debugging which is accomplished using the (InstallUtil.exe) in the framework directory. I usually create two batch files that points to the service executable and points to the InstallUtil so it's easier to install/remove the service when you want to test it on your development machine.
Note: In the comment by mastoo which is important is that you don't want use the general timers but (System.Threading.Timer)

Windows Service Applications  
http://msdn.microsoft.com/en-us/library/y817hyb6(v=VS.80).aspx 

How to: Write Services Programmatically  
http://msdn.microsoft.com/en-us/library/76477d2t(v=VS.80).aspx 

How to: Install and Uninstall Services  
http://msdn.microsoft.com/en-us/library/sd8zc8ha(v=VS.80).aspx 

How to: Specify the Security Context for Services  
http://msdn.microsoft.com/en-us/library/0x72fzyf(v=VS.80).aspx 

Public Class UserService1
    Inherits System.ServiceProcess.ServiceBase

    Shared Sub Main()

        System.ServiceProcess.ServiceBase.Run(New UserService1)

    End Sub

    Private Sub InitializeComponent()
        '
        'UserService1
        '
        Me.ServiceName = "MyService1"
        Me.CanHandlePowerEvent = False
        Me.CanHandleSessionChangeEvent = False
        Me.CanShutdown = True

    End Sub


    Protected Overrides Sub OnStart(ByVal args() As String)

        Dragon.Wake()

        MyBase.OnStart(args)
    End Sub


    Protected Overrides Sub OnStop()

        Dragon.Kill()

        MyBase.OnStop()
    End Sub

    '
    '   Dragon
    '
    Public Class Dragon

        Private Shared t As System.Threading.Timer = Nothing

        Public Shared Sub Wake()
            '// (BreathFire) every 5 seconds.
            t = New System.Threading.Timer(AddressOf BreathFire, Nothing, 5000, 5000)
        End Sub

        Public Shared Sub Kill()
            t.Dispose()
        End Sub

        Private Shared Sub BreathFire(ByVal state As Object)
            '// Add your code here.
        End Sub

    End Class

End Class

Open in new window

Author

Commented:
Hi,

How can I get this to work with field and non-shared functions?

Top Expert 2010
Commented:
I don't use the service template, basically what is easiest atleast for me is to start a new *empty project then add the following references to the project.

System.ServiceProcess
System.Configuration.Install
Add a new class module and add the service code to that class. After you do that double click the class then right click on grey work area and choose Add Installer.

Public Class UserService1
    Inherits System.ServiceProcess.ServiceBase

    Private t As System.Threading.Timer = Nothing

    Shared Sub Main()

        System.ServiceProcess.ServiceBase.Run(New UserService1)

    End Sub

    Private Sub InitializeComponent()
        '
        'UserService1 
        '
        Me.ServiceName = "MyService1"
        Me.CanHandlePowerEvent = False
        Me.CanHandleSessionChangeEvent = False
        Me.CanShutdown = True

    End Sub


    Protected Overrides Sub OnStart(ByVal args() As String)

        t = New System.Threading.Timer(AddressOf BreathFire, Nothing, 5000, 5000)

        MyBase.OnStart(args)
    End Sub


    Protected Overrides Sub OnStop()

        t.Dispose()

        MyBase.OnStop()
    End Sub

    '
    '   Timer Callback
    '
    Private Sub BreathFire(ByVal state As Object)
      
        '// Add your code here.
    End Sub


End Class

Open in new window

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial