Results 1 to 6 of 6

Thread: Windows Service, Using timer, VB.net

  1. #1

    Thread Starter
    New Member
    Join Date
    Apr 2016
    Posts
    6

    Talking Windows Service, Using timer, VB.net

    Hi everyone. I am kind of newbie when it comes to writing windows services but I'm pretty sure the problem I'm experiencing is not just a mistake in understanding.
    I had set up a windows service and had it working, firing off a timer every 60 seconds and writing an entry into my EventLog. It appears as if the minute I place any other code into it and I mean any other code, the timer stops working and won't even write the log entry.

    I would think if it were a problem with some piece of the code following it; that it would at least write that line and then error.

    Anyway Here is what I'm doing. I'm hoping maybe someone who has gone through this could give me a little direction to kick start the issue. Thanks in advance.
    Code:
    Imports System.Runtime.InteropServices
    Imports WinSCP
    Imports System.Threading
    
    Public Class MyNewService
        Public eventID As Integer
        Declare Auto Function SetServiceStatus Lib "advapi32.dll" (ByVal handle As IntPtr, ByRef serviceStatus As ServiceStatus) As Boolean
        Public Sub New()
            MyBase.New()
    
            ' This call is required by the designer.
            InitializeComponent()
            Try
                ' Add any initialization after the InitializeComponent() call.
                Me.EventLog1 = New System.Diagnostics.EventLog
                If Not System.Diagnostics.EventLog.SourceExists("MyNewService") Then
                    System.Diagnostics.EventLog.CreateEventSource("MyNewService", "MyNewLog")
                End If
                EventLog1.Source = "MyNewService"
                EventLog1.Log = "MyNewLog"
            Catch err As System.Diagnostics.Eventing.Reader.EventLogException
                MsgBox(err.InnerException)
            End Try
        End Sub
    
        Protected Overrides Sub OnStart(ByVal args() As String)
    
            Dim serviceStatus As ServiceStatus = New ServiceStatus()
            serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING
            serviceStatus.dwWaitHint = 100000
            SetServiceStatus(Me.ServiceHandle, serviceStatus)
    
            serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING
            SetServiceStatus(Me.ServiceHandle, serviceStatus)
    
            ' Add code here to start your service. This method should set things
            ' in motion so your service can do its work.
            EventLog1.WriteEntry("Service Started")
            
            Dim timer As System.Timers.Timer = New System.Timers.Timer()
            timer.Enabled = True
            timer.Interval = 60000
            AddHandler timer.Elapsed, AddressOf Me.OnTimer
            timer.Start()
        End Sub
    
        Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs)
            ' TODO: Insert Monitoring Activies Here.
            Try
                EventLog1.WriteEntry("Checking For New Files", EventLogEntryType.Information, eventID)
    
    
                ' Setup session options
                Dim sessionOptions As New SessionOptions
                EventLog1.WriteEntry("SessionOptions", EventLogEntryType.Information, eventID)
                With sessionOptions
                    .Protocol = Protocol.Sftp
                    .HostName = "XXXXXXXXXXX"
                    .UserName = "XXXXXXXXXXX"
                    .Password = "XXXXXXXXXXX"
                    .SshHostKeyFingerprint = "XXXXXXXXXXXXXXXX"
                End With
    
                Using session As New Session
                    ' Connect
                    session.Open(sessionOptions)
                    EventLog1.WriteEntry("Session To Cheyney FTP Open")
    
                    ' Download files
                    Dim transferOptions As New TransferOptions
                    transferOptions.TransferMode = TransferMode.Binary
    
                    Dim transferResult As TransferOperationResult
                    transferResult = session.GetFiles("/Inbox1/*", "C:\Localfolder\", False, transferOptions)
    
                    ' Throw on any error
                    transferResult.Check()
    
                    ' Print results
                    For Each transfer In transferResult.Transfers
                        EventLog1.WriteEntry(".....Transferring File:" & transfer.filename)
                    Next
                End Using
    
    
    
            Catch err As Exception
                EventLog1.WriteEntry("Service Exception: " & err.InnerException.ToString)
    
    
            End Try
    
    
    
            eventID = eventID + 1
        End Sub
    
        Protected Overrides Sub OnStop()
            Dim serviceStatus As ServiceStatus = New ServiceStatus()
            serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED
            SetServiceStatus(Me.ServiceHandle, serviceStatus)
            ' Add code here to perform any tear-down necessary to stop your service.
            EventLog1.WriteEntry("Service Stopped")
        End Sub
    
    
        Public Enum ServiceState
            SERVICE_STOPPED = 1
            SERVICE_START_PENDING = 2
            SERVICE_STOP_PENDING = 3
            SERVICE_RUNNING = 4
            SERVICE_CONTINUE_PENDING = 5
            SERVICE_PAUSE_PENDING = 6
            SERVICE_PAUSED = 7
        End Enum
    
        <StructLayout(LayoutKind.Sequential)>
        Public Structure ServiceStatus
            Public dwServiceType As Long
            Public dwCurrentState As ServiceState
            Public dwControlsAccepted As Long
            Public dwWin32ExitCode As Long
            Public dwServiceSpecificExitCode As Long
            Public dwCheckPoint As Long
            Public dwWaitHint As Long
        End Structure
    
    End Class
    Last edited by Shaggy Hiker; May 28th, 2017 at 10:45 AM. Reason: Added CODE tags.

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Windows Service, Using timer, VB.net

    For future reference, please us appropriate formatting tags when posting code snippets.
    vb.net Code:
    1. Imports System.Runtime.InteropServices
    2. Imports WinSCP
    3. Imports System.Threading
    4.  
    5. Public Class MyNewService
    6.     Public eventID As Integer
    7.     Declare Auto Function SetServiceStatus Lib "advapi32.dll" (ByVal handle As IntPtr, ByRef serviceStatus As ServiceStatus) As Boolean
    8.     Public Sub New()
    9.         MyBase.New()
    10.  
    11.         ' This call is required by the designer.
    12.         InitializeComponent()
    13.         Try
    14.             ' Add any initialization after the InitializeComponent() call.
    15.             Me.EventLog1 = New System.Diagnostics.EventLog
    16.             If Not System.Diagnostics.EventLog.SourceExists("MyNewService") Then
    17.                 System.Diagnostics.EventLog.CreateEventSource("MyNewService", "MyNewLog")
    18.             End If
    19.             EventLog1.Source = "MyNewService"
    20.             EventLog1.Log = "MyNewLog"
    21.         Catch err As System.Diagnostics.Eventing.Reader.EventLogException
    22.             MsgBox(err.InnerException)
    23.         End Try
    24.     End Sub
    25.  
    26.     Protected Overrides Sub OnStart(ByVal args() As String)
    27.  
    28.         Dim serviceStatus As ServiceStatus = New ServiceStatus()
    29.         serviceStatus.dwCurrentState = ServiceState.SERVICE_START_PENDING
    30.         serviceStatus.dwWaitHint = 100000
    31.         SetServiceStatus(Me.ServiceHandle, serviceStatus)
    32.  
    33.         serviceStatus.dwCurrentState = ServiceState.SERVICE_RUNNING
    34.         SetServiceStatus(Me.ServiceHandle, serviceStatus)
    35.  
    36.         ' Add code here to start your service. This method should set things
    37.         ' in motion so your service can do its work.
    38.         EventLog1.WriteEntry("Service Started")
    39.        
    40.         Dim timer As System.Timers.Timer = New System.Timers.Timer()
    41.         timer.Enabled = True
    42.         timer.Interval = 60000
    43.         AddHandler timer.Elapsed, AddressOf Me.OnTimer
    44.         timer.Start()
    45.     End Sub
    46.  
    47.     Private Sub OnTimer(sender As Object, e As Timers.ElapsedEventArgs)
    48.         ' TODO: Insert Monitoring Activies Here.
    49.         Try
    50.             EventLog1.WriteEntry("Checking For New Files", EventLogEntryType.Information, eventID)
    51.  
    52.  
    53.             ' Setup session options
    54.             Dim sessionOptions As New SessionOptions
    55.             EventLog1.WriteEntry("SessionOptions", EventLogEntryType.Information, eventID)
    56.             With sessionOptions
    57.                 .Protocol = Protocol.Sftp
    58.                 .HostName = "XXXXXXXXXXX"
    59.                 .UserName = "XXXXXXXXXXX"
    60.                 .Password = "XXXXXXXXXXX"
    61.                 .SshHostKeyFingerprint = "XXXXXXXXXXXXXXXX"
    62.             End With
    63.  
    64.             Using session As New Session
    65.                 ' Connect
    66.                 session.Open(sessionOptions)
    67.                 EventLog1.WriteEntry("Session To Cheyney FTP Open")
    68.  
    69.                 ' Download files
    70.                 Dim transferOptions As New TransferOptions
    71.                 transferOptions.TransferMode = TransferMode.Binary
    72.  
    73.                 Dim transferResult As TransferOperationResult
    74.                 transferResult = session.GetFiles("/Inbox1/*", "C:\Localfolder\", False, transferOptions)
    75.  
    76.                 ' Throw on any error
    77.                 transferResult.Check()
    78.  
    79.                 ' Print results
    80.                 For Each transfer In transferResult.Transfers
    81.                     EventLog1.WriteEntry(".....Transferring File:" & transfer.filename)
    82.                 Next
    83.             End Using
    84.  
    85.  
    86.  
    87.         Catch err As Exception
    88.             EventLog1.WriteEntry("Service Exception: " & err.InnerException.ToString)
    89.  
    90.  
    91.         End Try
    92.  
    93.  
    94.  
    95.         eventID = eventID + 1
    96.     End Sub
    97.  
    98.     Protected Overrides Sub OnStop()
    99.         Dim serviceStatus As ServiceStatus = New ServiceStatus()
    100.         serviceStatus.dwCurrentState = ServiceState.SERVICE_STOPPED
    101.         SetServiceStatus(Me.ServiceHandle, serviceStatus)
    102.         ' Add code here to perform any tear-down necessary to stop your service.
    103.         EventLog1.WriteEntry("Service Stopped")
    104.     End Sub
    105.  
    106.  
    107.     Public Enum ServiceState
    108.         SERVICE_STOPPED = 1
    109.         SERVICE_START_PENDING = 2
    110.         SERVICE_STOP_PENDING = 3
    111.         SERVICE_RUNNING = 4
    112.         SERVICE_CONTINUE_PENDING = 5
    113.         SERVICE_PAUSE_PENDING = 6
    114.         SERVICE_PAUSED = 7
    115.     End Enum
    116.  
    117.     <StructLayout(LayoutKind.Sequential)>
    118.     Public Structure ServiceStatus
    119.         Public dwServiceType As Long
    120.         Public dwCurrentState As ServiceState
    121.         Public dwControlsAccepted As Long
    122.         Public dwWin32ExitCode As Long
    123.         Public dwServiceSpecificExitCode As Long
    124.         Public dwCheckPoint As Long
    125.         Public dwWaitHint As Long
    126.     End Structure
    127.  
    128. End Class
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,102

    Re: Windows Service, Using timer, VB.net

    I edited the post to add [CODE][/CODE] tags, which you can do by pressing the # button and pasting the code between the resulting tags. The other type of formatting, which JMC showed, results from the VB button (which looks like VE on most browsers). I find the CODE tags a bit easier, and that code copies and pastes a bit more easily, but doesn't look as nice in the post.

    As to the question: Where do you add this code that causes the problem? I suppose I'd also ask what that code would be, but from the way you asked the question, I assume it could be a wide variety of anything. Perhaps an example may be useful, but I think the location might be the most important part.
    My usual boring signature: Nothing

  4. #4
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Windows Service, Using timer, VB.net

    Here's a guess, this is a bit subtle.

    When you create the timer, you store it in a variable that is local to OnStart(). When OnStart() ends, that variable doesn't exist anymore, so nothing references the Timer. That means the next time the Garbage Collector runs, it can decide to destroy the Timer.

    If you want something to live as long as your Service, it should be a field of a class that stays in memory. There's a few ways to go about it, the easiest would be to make the Timer a Shared field of your MyNewService class.
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

  5. #5

    Thread Starter
    New Member
    Join Date
    Apr 2016
    Posts
    6

    Re: Windows Service, Using timer, VB.net

    Still doesn't work. IF there is an exception occurring when the first object is defined WHY doesn't the try..catch... grab an error. Since it doesn't I can only assume there wasn't one!

  6. #6
    You don't want to know.
    Join Date
    Aug 2010
    Posts
    4,578

    Re: Windows Service, Using timer, VB.net

    There's a couple of reasons an exception could be being thrown but not displayed to you.

    First, you're only catching one kind of exception. If any other kind of exception is being thrown, you don't handle that one.

    Second, services can't display UI by default, so even if it's the exception you expect the MsgBox() call might be ignored.

    Replace it with something that catches any exception andwrites the exception to a file, generally you can do that without issue. Something like:
    Code:
    Catch ex As Exception
        Dim desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop)
        Dim filePath = Path.Combine(desktopPath, "serviceLog.txt")
        File.WriteAllText(filePath, ex.ToString())
    End Try
    This answer is wrong. You should be using TableAdapter and Dictionaries instead.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width