Go Back  Xtreme Visual Basic Talk > Visual Basic .NET (2002/2003/2005/2008, including Express editions) > .NET General > Writing Services with .NET Express


Reply
 
Thread Tools Display Modes
  #1  
Old 05-15-2008, 05:29 AM
AstroTux's Avatar
AstroTux AstroTux is offline
Junior Contributor
 
Join Date: Aug 2007
Posts: 345
Default Writing Services with .NET Express

Hi,

Is this possible??

Best regards,
AstroTux.
Reply With Quote
  #2  
Old 05-15-2008, 07:42 AM
darkforcesjedi's Avatar
darkforcesjedi darkforcesjedi is offline
Trust me, I'm an

* Expert *
 
Join Date: Apr 2001
Location: In ur base, pwnin d00dz
Posts: 1,961
Default

Any windows executable can be run as a service on Windows NT/2000/XP. I don't have Vista, but I assume it can be done there too. Services are defined in the registry.
__________________
To err is human; to debug, divine.
Reply With Quote
  #3  
Old 05-19-2008, 08:14 AM
AstroTux's Avatar
AstroTux AstroTux is offline
Junior Contributor
 
Join Date: Aug 2007
Posts: 345
Default

Hmm! So I can create a windows app without a GUI front-end for example, add it to the registry and that's it?

Seems a bit too easy... I've read somewhere about Services class, and writing Start/Stop/Pause routines etc.. ????

Best regards,
AstroTux.
Reply With Quote
  #4  
Old 05-19-2008, 10:09 AM
darkforcesjedi's Avatar
darkforcesjedi darkforcesjedi is offline
Trust me, I'm an

* Expert *
 
Join Date: Apr 2001
Location: In ur base, pwnin d00dz
Posts: 1,961
Default

Here check this out:
http://www.devarticles.com/c/a/VB.Ne...ice-in-VB.NET/

If you simply define an executable in the registry as a service, it will start, but you will not be able to interact with it like a normal service. Some virii do this to monitor the existence of certain files or recreate themselves when you delete them. A while back I tried replacing a virus service executable with another EXE and it ran.

.NET has the tools you need to make a real service though.
__________________
To err is human; to debug, divine.
Reply With Quote
  #5  
Old 05-19-2008, 10:18 AM
AtmaWeapon's Avatar
AtmaWeapon AtmaWeapon is online now
Ultimate Contributor

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 7,598
Default

It's actually pretty easy, but you're going to have to do a little bit of footwork since you're using the Express edition of Visual Studio. The commercial versions have project templates and build actions that make this process a little easier, but there's nothing stopping you from doing the work yourself.

In fact, the answer to the question "Can the Express edition do..." is always yes if it's something built into the .NET framework; in fact, the answer is "Notepad can do it". I'm not going to be that hardcore though. I just manually created a service without using the project templates, and I'll walk you through the process.

Initial Project Setup
First, create a new project. If it's available, choose the "Empty project" template. The first thing you need to do is add a reference to System.ServiceProcess.dll and System.Configuration.Install.dll.

Create ServiceBase subclass
The ServiceBase class is a class that all Windows services must derive from. It provides methods such as OnStart and OnStop that you can override in order to handle service events. This class is where your service does things. For our example, we'll make a service that monitors the My Documents folder and writes to a log file whenever a file is created. The implementation is pretty simple:
Code:
Imports System.ServiceProcess
Imports System.IO

Public Class DemoService
    Inherits ServiceBase

    Friend Const DemoServiceName As String = "DemoService"

    Private _watcher As FileSystemWatcher
    Private _logFilePath As String

    Public Sub New()
        Me.ServiceName = DemoServiceName
        Me.CanHandlePowerEvent = False
        Me.CanHandleSessionChangeEvent = False
        Me.CanPauseAndContinue = False
        Me.CanShutdown = True
        Me.CanStop = True

        _watcher = New FileSystemWatcher()
        _watcher.Path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
        AddHandler _watcher.Created, AddressOf WatcherOnCreated

        ' Log file goes in application data directory
        _logFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
        _logFilePath = Path.Combine(_logFilePath, "DemoService")
        _logFilePath = Path.Combine(_logFilePath, "log.txt")
    End Sub

    Protected Overrides Sub OnShutdown()
        MyBase.OnShutdown()
        RemoveHandler _watcher.Created, AddressOf WatcherOnCreated
        _watcher.Dispose()
    End Sub

    ' When the service is started, we tell the watcher to listen for events
    Protected Overrides Sub OnStart(ByVal args() As String)
        MyBase.OnStart(args)
        _watcher.EnableRaisingEvents = True
    End Sub

    ' When the service is stopped, we tell the watcher to stop listening for events
    Protected Overrides Sub OnStop()
        MyBase.OnStop()
        _watcher.EnableRaisingEvents = False
    End Sub

    Private Sub WatcherOnCreated(ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs)
        If Not Directory.Exists(Path.GetDirectoryName(_logFilePath)) Then
            Directory.CreateDirectory(Path.GetDirectoryName(_logFilePath))
        End If

        Using writer = New StreamWriter(_logFilePath, True)
            Dim messageTemplate As String = "{0}: File {1} created."

            writer.WriteLine(messageTemplate, DateTime.Now, e.Name)
        End Using
    End Sub

End Class
Notice I indicated that all the user can do with this service is start it, stop it, or shut it down. It's pretty simple: it creates the watcher in the constructor, starts the watcher's events when the service is started, and stops the watcher's events when the service is stopped. Now, we have to make something that can run it.

Runner Stub Setup
In Windows Forms applications, you use the Application class to get things started. In a Windows Service, you need to use ServiceBase. Add a new class to the project named Program, and paste this code in:
Code:
Imports System.ServiceProcess

Public Class Program

    Public Shared Sub Main()
        Dim servicesToRun As ServiceBase()

        servicesToRun = New ServiceBase() {New DemoService}

        ServiceBase.Run(servicesToRun)
    End Sub

End Class
Basically, this creates a list of the services we want to run (which is only one in this case) and runs them. Easy, but required. Now we have to make sure the project is configured properly. Open the project properties and make sure it is set to be a Windows Forms application with Sub Main as the startup object, and double-check that "Enable application framework" is NOT checked. Now, we have to create the code that installs the process.

Creating Process Installers
To install a process, we need a ServiceProcessInstaller to describe the parameters for the process that will run the service, and a ServiceInstaller to describe the parameters for installing the service. These must be contained in an instance of the Installer class that is marked with RunInstallerAttribute. It's a lot easier than it sounds; add a class named [i]DemoServiceInstaller to your class:
Code:
Imports System.Configuration.Install
Imports System.ServiceProcess

<System.ComponentModel.RunInstaller(True)> _
Public Class DemoServiceInstaller
    Inherits Installer

    Private _processInstaller As ServiceProcessInstaller
    Private _serviceInstaller As ServiceInstaller

    Public Sub New()
        MyBase.New()
        _processInstaller = New ServiceProcessInstaller()
        ' LocalService can't access the filesystem, and we want to log to a file; provide a user
        ' and password during the install step.
        _processInstaller.Account = ServiceAccount.User

        _serviceInstaller = New ServiceInstaller()
        _serviceInstaller.Description = "Logs any files created in the My Documents folder."
        _serviceInstaller.DisplayName = "My Documents Watcher"
        Me.Installers.Add(_processInstaller)
        Me.Installers.Add(_serviceInstaller)
        ' Note this has to match the name defined by the service class exactly; I'm using an
        ' internal constant to guarantee this.
        _serviceInstaller.ServiceName = DemoService.DemoServiceName
        _serviceInstaller.StartType = ServiceStartMode.Manual
    End Sub

End Class
It's pretty straightforward; each property is easy to figure out. The only thing to be aware of here is that I set the account type to "User", which means you'll need to give it a username and password later. I wanted to give it an account type of "LocalService", but that account is not allowed to write to the filesystem and I'm using a log file. Ideally, in this case you would create a very limited-privilege user for the service that can only access what it needs; I just used my own account when prompted.

Installing the process
Now that we've got the service, the runner, and the installer, we are ready to install the process. You can manually edit the registry to do this, but it's a lot nicer to let tools do the work for you. The InstallUtil tool is designed to find the service installers in an assembly and install the services for you. Open up the Visual Studio 2008 command prompt and navigate to the build output directory. Then, type InstallUtil DemoService.exe and if everything goes well, the service should be installed (after prompting for a username and password, of course). Open the services applet from Control Panel and look for "My Documents Watcher" in the list; right-click it and start it. Now, when files are created in the My Documents folder, the log file should be updated.

You should do a little reading in the documentation about how services work, and probably read a few articles. All I really covered is how to get a service installed without using the VS tools, and I do not claim I'm following best practices.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:

Powered by liquidweb