Generate Barcode from Service | VB.NETByteScout Barcode SDK

Generate Barcode from Service | VB.NET

Form1.vb:

VB
Imports System
Imports System.IO
Imports System.Management
Imports System.Windows.Forms
Imports System.ServiceProcess

Public Partial Class Form1
    Inherits Form
    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub btnInstallService_Click(sender As Object, e As EventArgs)
        Try
            ' Install the service
            ServiceInstaller.Install("Service1", "Service1", Path.GetFullPath("WindowsService1.exe"))

            ' Set the service option "Allow desktop interaction".
            Dim co As New ConnectionOptions()
            co.Impersonation = ImpersonationLevel.Impersonate
            Dim mgmtScope As New ManagementScope("root\CIMV2", co)
            mgmtScope.Connect()
            Dim wmiService As New ManagementObject("Win32_Service.Name='Service1'")
            Dim InParam As ManagementBaseObject = wmiService.GetMethodParameters("Change")
            InParam("DesktopInteract") = True
            Dim OutParam As ManagementBaseObject = wmiService.InvokeMethod("Change", InParam, Nothing)

            ' Start the service
            ServiceInstaller.StartService("Service1")
        Catch exception As Exception
            MessageBox.Show(exception.Message)
        End Try
    End Sub

    Private Sub btnUninstallService_Click(sender As Object, e As EventArgs)
        Try
            ServiceInstaller.Uninstall("Service1")
        Catch exception As Exception
            MessageBox.Show(exception.Message)
        End Try
    End Sub

    Private Sub btnExit_Click(sender As Object, e As EventArgs)
        Me.Close()
    End Sub
End Class

Program.vb:

VB
Imports System.Collections.Generic
Imports System.Windows.Forms

NotInheritable Class Program
    Private Sub New()
    End Sub
    ''' <summary>
    ''' The main entry point for the application.
    ''' </summary>
    <STAThread> _
    Friend Shared Sub Main()
        Application.EnableVisualStyles()
        Application.SetCompatibleTextRenderingDefault(False)
        Application.Run(New Form1())
    End Sub
End Class

ServiceInstaller.vb:

VB
Imports System
Imports System.Runtime.InteropServices
Imports System.Threading

Public NotInheritable Class ServiceInstaller
    Private Sub New()
    End Sub
    Private Const STANDARD_RIGHTS_REQUIRED As Integer = &Hf0000
    Private Const SERVICE_WIN32_OWN_PROCESS As Integer = &H10

    <StructLayout(LayoutKind.Sequential)> _
    Private Class SERVICE_STATUS
        Public dwServiceType As Integer = 0
        Public dwCurrentState As ServiceState = 0
        Public dwControlsAccepted As Integer = 0
        Public dwWin32ExitCode As Integer = 0
        Public dwServiceSpecificExitCode As Integer = 0
        Public dwCheckPoint As Integer = 0
        Public dwWaitHint As Integer = 0
    End Class

    #Region "OpenSCManager"
    Private Declare Unicode Function OpenSCManager Lib "advapi32.dll" Alias "OpenSCManagerW" (machineName As String, databaseName As String, dwDesiredAccess As ScmAccessRights) As IntPtr
    #End Region

    #Region "OpenService"
    <DllImport("advapi32.dll", SetLastError := True, CharSet := CharSet.Auto)> _
    Private Shared Function OpenService(hSCManager As IntPtr, lpServiceName As String, dwDesiredAccess As ServiceAccessRights) As IntPtr
    End Function
    #End Region

    #Region "CreateService"
    <DllImport("advapi32.dll", SetLastError := True, CharSet := CharSet.Auto)> _
    Private Shared Function CreateService(hSCManager As IntPtr, lpServiceName As String, lpDisplayName As String, dwDesiredAccess As ServiceAccessRights, dwServiceType As Integer, dwStartType As ServiceBootFlag, _
        dwErrorControl As ServiceError, lpBinaryPathName As String, lpLoadOrderGroup As String, lpdwTagId As IntPtr, lpDependencies As String, lp As String, _
        lpPassword As String) As IntPtr
    End Function
    #End Region

    #Region "CloseServiceHandle"
    <DllImport("advapi32.dll", SetLastError := True)> _
    Private Shared Function CloseServiceHandle(hSCObject As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    #End Region

    #Region "QueryServiceStatus"
    <DllImport("advapi32.dll")> _
    Private Shared Function QueryServiceStatus(hService As IntPtr, lpServiceStatus As SERVICE_STATUS) As Integer
    End Function
    #End Region

    #Region "DeleteService"
    <DllImport("advapi32.dll", SetLastError := True)> _
    Private Shared Function DeleteService(hService As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    #End Region

    #Region "ControlService"
    <DllImport("advapi32.dll")> _
    Private Shared Function ControlService(hService As IntPtr, dwControl As ServiceControl, lpServiceStatus As SERVICE_STATUS) As Integer
    End Function
    #End Region

    #Region "StartService"
    <DllImport("advapi32.dll", SetLastError := True)> _
    Private Shared Function StartService(hService As IntPtr, dwNumServiceArgs As Integer, lpServiceArgVectors As Integer) As Integer
    End Function
    #End Region

    Public Shared Sub Uninstall(serviceName As String)
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.AllAccess)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.AllAccess)
            If service = IntPtr.Zero Then
                Throw New ApplicationException("Service not installed.")
            End If

            Try
                StopService(service)
                If Not DeleteService(service) Then
                    Throw New ApplicationException("Could not delete service " & Marshal.GetLastWin32Error())
                End If
            Finally
                CloseServiceHandle(service)
            End Try
        Finally
            CloseServiceHandle(scm)
        End Try
    End Sub

    Public Shared Function ServiceIsInstalled(serviceName As String) As Boolean
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.Connect)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus)

            If service = IntPtr.Zero Then
                Return False
            End If

            CloseServiceHandle(service)
            Return True
        Finally
            CloseServiceHandle(scm)
        End Try
    End Function

    Public Shared Sub Install(serviceName As String, displayName As String, fileName As String)
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.AllAccess)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.AllAccess)

            If service = IntPtr.Zero Then
                service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_WIN32_OWN_PROCESS, ServiceBootFlag.AutoStart, _
                    ServiceError.Normal, fileName, Nothing, IntPtr.Zero, Nothing, Nothing, _
                    Nothing)
            End If

            If service = IntPtr.Zero Then
                Throw New ApplicationException("Failed to install service.")
            End If
        Finally
            CloseServiceHandle(scm)
        End Try
    End Sub

    Public Shared Sub InstallAndStart(serviceName As String, displayName As String, fileName As String)
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.AllAccess)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.AllAccess)

            If service = IntPtr.Zero Then
                service = CreateService(scm, serviceName, displayName, ServiceAccessRights.AllAccess, SERVICE_WIN32_OWN_PROCESS, ServiceBootFlag.AutoStart, _
                    ServiceError.Normal, fileName, Nothing, IntPtr.Zero, Nothing, Nothing, _
                    Nothing)
            End If

            If service = IntPtr.Zero Then
                Throw New ApplicationException("Failed to install service.")
            End If

            Try
                StartService(service)
            Finally
                CloseServiceHandle(service)
            End Try
        Finally
            CloseServiceHandle(scm)
        End Try
    End Sub

    Public Shared Sub StartService(serviceName As String)
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.Connect)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus Or ServiceAccessRights.Start)
            If service = IntPtr.Zero Then
                Throw New ApplicationException("Could not open service.")
            End If

            Try
                StartService(service)
            Finally
                CloseServiceHandle(service)
            End Try
        Finally
            CloseServiceHandle(scm)
        End Try
    End Sub

    Public Shared Sub StopService(serviceName As String)
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.Connect)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus Or ServiceAccessRights.[Stop])
            If service = IntPtr.Zero Then
                Throw New ApplicationException("Could not open service.")
            End If

            Try
                StopService(service)
            Finally
                CloseServiceHandle(service)
            End Try
        Finally
            CloseServiceHandle(scm)
        End Try
    End Sub

    Private Shared Sub StartService(service As IntPtr)
        Dim status As New SERVICE_STATUS()
        StartService(service, 0, 0)
        Dim changedStatus As Boolean = WaitForServiceStatus(service, ServiceState.StartPending, ServiceState.Running)
        If Not changedStatus Then
            Throw New ApplicationException("Unable to start service")
        End If
    End Sub

    Private Shared Sub StopService(service As IntPtr)
        Dim status As New SERVICE_STATUS()
        ControlService(service, ServiceControl.[Stop], status)
        Dim changedStatus As Boolean = WaitForServiceStatus(service, ServiceState.StopPending, ServiceState.Stopped)
        If Not changedStatus Then
            Throw New ApplicationException("Unable to stop service")
        End If
    End Sub

    Public Shared Function GetServiceStatus(serviceName As String) As ServiceState
        Dim scm As IntPtr = OpenSCManager(ScmAccessRights.Connect)

        Try
            Dim service As IntPtr = OpenService(scm, serviceName, ServiceAccessRights.QueryStatus)
            If service = IntPtr.Zero Then
                Return ServiceState.NotFound
            End If

            Try
                Return GetServiceStatus(service)
            Finally
                CloseServiceHandle(service)
            End Try
        Finally
            CloseServiceHandle(scm)
        End Try
    End Function

    Private Shared Function GetServiceStatus(service As IntPtr) As ServiceState
        Dim status As New SERVICE_STATUS()

        If QueryServiceStatus(service, status) = 0 Then
            Throw New ApplicationException("Failed to query service status.")
        End If

        Return status.dwCurrentState
    End Function

    Private Shared Function WaitForServiceStatus(service As IntPtr, waitStatus As ServiceState, desiredStatus As ServiceState) As Boolean
        Dim status As New SERVICE_STATUS()

        QueryServiceStatus(service, status)
        If status.dwCurrentState = desiredStatus Then
            Return True
        End If

        Dim dwStartTickCount As Integer = Environment.TickCount
        Dim dwOldCheckPoint As Integer = status.dwCheckPoint

        While status.dwCurrentState = waitStatus
            ' Do not wait longer than the wait hint. A good interval is
            ' one tenth the wait hint, but no less than 1 second and no
            ' more than 10 seconds.

            Dim dwWaitTime As Integer = status.dwWaitHint \ 10

            If dwWaitTime < 1000 Then
                dwWaitTime = 1000
            ElseIf dwWaitTime > 10000 Then
                dwWaitTime = 10000
            End If

            Thread.Sleep(dwWaitTime)

            ' Check the status again.

            If QueryServiceStatus(service, status) = 0 Then
                Exit While
            End If

            If status.dwCheckPoint > dwOldCheckPoint Then
                ' The service is making progress.
                dwStartTickCount = Environment.TickCount
                dwOldCheckPoint = status.dwCheckPoint
            Else
                If Environment.TickCount - dwStartTickCount > status.dwWaitHint Then
                    ' No progress made within the wait hint
                    Exit While
                End If
            End If
        End While
        Return (status.dwCurrentState = desiredStatus)
    End Function

    Private Shared Function OpenSCManager(rights As ScmAccessRights) As IntPtr
        Dim scm As IntPtr = OpenSCManager(Nothing, Nothing, rights)
        If scm = IntPtr.Zero Then
            Throw New ApplicationException("Could not connect to service control manager.")
        End If

        Return scm
    End Function
End Class

Public Enum ServiceState
    Unknown = -1
    ' The state cannot be (has not been) retrieved.
    NotFound = 0
    ' The service is not known on the host server.
    Stopped = 1
    StartPending = 2
    StopPending = 3
    Running = 4
    ContinuePending = 5
    PausePending = 6
    Paused = 7
End Enum

<Flags> _
Public Enum ScmAccessRights
    Connect = &H1
    CreateService = &H2
    EnumerateService = &H4
    Lock = &H8
    QueryLockStatus = &H10
    ModifyBootConfig = &H20
    StandardRightsRequired = &Hf0000
    AllAccess = (StandardRightsRequired Or Connect Or CreateService Or EnumerateService Or Lock Or QueryLockStatus Or ModifyBootConfig)
End Enum

<Flags> _
Public Enum ServiceAccessRights
    QueryConfig = &H1
    ChangeConfig = &H2
    QueryStatus = &H4
    EnumerateDependants = &H8
    Start = &H10
    [Stop] = &H20
    PauseContinue = &H40
    Interrogate = &H80
    UserDefinedControl = &H100
    Delete = &H10000
    StandardRightsRequired = &Hf0000
    AllAccess = (StandardRightsRequired Or QueryConfig Or ChangeConfig Or QueryStatus Or EnumerateDependants Or Start Or [Stop] Or PauseContinue Or Interrogate Or UserDefinedControl)
End Enum

Public Enum ServiceBootFlag
    Start = &H0
    SystemStart = &H1
    AutoStart = &H2
    DemandStart = &H3
    Disabled = &H4
End Enum

Public Enum ServiceControl
    [Stop] = &H1
    Pause = &H2
    [Continue] = &H3
    Interrogate = &H4
    Shutdown = &H5
    ParamChange = &H6
    NetBindAdd = &H7
    NetBindRemove = &H8
    NetBindEnable = &H9
    NetBindDisable = &Ha
End Enum

Public Enum ServiceError
    Ignore = &H0
    Normal = &H1
    Severe = &H2
    Critical = &H3
End Enum

Program.vb:

VB
Imports System.Collections.Generic
Imports System.ServiceProcess
Imports System.Text

NotInheritable Class Program
    Private Sub New()
    End Sub
    ''' <summary>
    ''' The main entry point for the application.
    ''' </summary>
    Friend Shared Sub Main()
        Dim servicesToRun As ServiceBase() = New ServiceBase() {New Service1()}

        ServiceBase.Run(servicesToRun)
    End Sub
End Class

ProjectInstaller.vb:

VB
Imports System.Collections
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Configuration.Install


<RunInstaller(True)> _
Public Partial Class ProjectInstaller
    Inherits System.Configuration.Install.Installer
    Public Sub New()
        InitializeComponent()
    End Sub
End Class

Service1.vb:

VB
Imports System.IO
Imports System.ServiceProcess
Imports System.Timers
Imports Bytescout.BarCode

Public Partial Class Service1
    Inherits ServiceBase
    Private _timer As Timer = Nothing

    Public Sub New()
        InitializeComponent()

        If Not System.Diagnostics.EventLog.SourceExists("MySource") Then
            System.Diagnostics.EventLog.CreateEventSource("MySource", "MyNewLog")
        End If

        eventLog1.Source = "MySource"
        eventLog1.Log = "MyNewLog"
    End Sub

    Protected Overrides Sub OnStart(args As String())
        eventLog1.WriteEntry("In OnStart")

        If _timer IsNot Nothing Then
            _timer.[Stop]()
            RemoveHandler _timer.Elapsed, AddressOf Timer_Elapsed
            _timer.Dispose()
        End If

        _timer = New Timer(5000)
        AddHandler _timer.Elapsed, AddressOf Timer_Elapsed
        _timer.Start()
    End Sub

    Protected Overrides Sub OnStop()
        eventLog1.WriteEntry("In OnStop.")

        If _timer IsNot Nothing Then
            _timer.[Stop]()
            RemoveHandler _timer.Elapsed, AddressOf Timer_Elapsed
            _timer.Dispose()
            _timer = Nothing
        End If
    End Sub

    Private Sub Timer_Elapsed(sender As Object, e As ElapsedEventArgs)
        Dim barcode As Barcode = Nothing

        Try
            ' Generate sample barcode value by random number
            Dim random As New Random()
            Dim barcodeValue As String = "(00)" & random.[Next]().ToString("000000000000000000")

            ' Create Bytescout.BarCode object and setup the barcode
            barcode = New Barcode("demo", "demo")
            barcode.Symbology = SymbologyType.GS1_128
            barcode.Value = barcodeValue

            Dim outputDirectory As String = "c:\barcodes"
            If Not Directory.Exists(outputDirectory) Then
                Directory.CreateDirectory(outputDirectory)
            End If

            Dim fileName As String = barcodeValue & ".pdf"
            Dim filePath As String = Path.Combine(outputDirectory, fileName)

            ' Save barcode to new PDF file
            barcode.DrawToNewPDF(filePath, 500, 500, 50, 50)


                ' Sending email message example:
                '
'                System.Net.Mail.MailMessage message = new System.Net.Mail.MailMessage();
'                message.To.Add("luckyperson@online.microsoft.com");
'                message.Subject = fileName;
'                message.From = new System.Net.Mail.MailAddress("From@online.microsoft.com");
'                message.Body = "This is the message body";
'                message.Attachments.Add(new System.Net.Mail.Attachment(filePath));
'                
'                System.Net.Mail.SmtpClient smtp = new System.Net.Mail.SmtpClient("your_smtp_host");
'                smtp.Send(message);
'                

            eventLog1.WriteEntry("Generated " & fileName)
        Catch exception As Exception
            eventLog1.WriteEntry(exception.Message)
        Finally
            If barcode IsNot Nothing Then
                barcode.Dispose()
            End If
        End Try
    End Sub
End Class

readme.txt:

This is simple .NET service created by Microsoft guidelines ( http://msdn.microsoft.com/en-us/library/d56de412(v=vs.80).aspx )
"ServiceController" - simple GUI application that starts and stops the service;
"WindowsService1" - service itself.

This sample service generates PDF files with random GS1-128 barcode every five seconds 
and puts them to "c:\barcodes" folder.

Check the Service1.cs file. 
There is barcode generation and email sending example code.

ServiceController requries Administrator rights to run, so you should run the Visual Studio as Administrator to be able to run the ServiceController from Debug. 
Or run the compiled executable directly. It will ask for Administrative rights on start.