By John M. Andre
20 February 2002
It is now possible to create an NT Service with VB. There are a few options on how to do his and the one I will discuss here is using NTSvc.ocx (an OCX provided by Microsoft specifically for writing NT Services in VB).
Download the control now (30KB)
To create an NT Service, start VB, create a new Standard EXE, add a reference to the Microsoft NT Service Control (NTSvc.ocx), and place an instance of this control on your form.
There are a few properties you will need to set on the control:
- Name = NTService
- DisplayName = the name you would like to be displayed in the Services control panel and in the event log (you can use spaces here)
- Interactive = True (to allow your service to interact with the desktop)
- ServiceName = the name of your service without spaces
- StartMode = Whichever start mode you would like your service to have when it gets installed (normally svcStartManual or svcStartAutomatic)
In the Form_Load event, you will want to add logic to test Command (the command-line parameters passed in) and conditionally install or uninstall your service. The code to do this is simple:
Select Case UCase(Command)
Case "-I", "/I"
If NTService.Install Then
MsgBox NTService.DisplayName & " installed successfully."
MsgBox NTService.DisplayName & " did not install successfully."
Case "-U", "/U"
If NTService.Uninstall Then
MsgBox NTService.DisplayName & " uninstalled successfully."
MsgBox NTService.DisplayName & " did not uninstall successfully."
'-- Application is started without parameters
MsgBox "The parameter: " & Command & " was not understood. Try -I (install) or -U (uninstall)."
In each routine’s error handler, you might want to write error information out to the Event Log. You could use the trusty App.LogEvent, but with NTSvc.ocx we have another option: NTService.LogEvent.
App.LogEvent shows as a source for all VB applications "VBRuntime." This is not very helpful when most of the applications you write are in VB. Luckily, NTService.LogEvent will use your NTService.DisplayName as the source in the Event Log. The calls looks like this:
NTService.LogEvent svcEventError, svcMessageError, Err.Description
NTService.LogEvent svcEventInformation, svcMessageInfo, "Something happened"
You will need to put some code in at least the following two events:
Private Sub NTService_Start (Success as Boolean)
'-- Add code to do what you want to do
' when the service starts
'-- Set the success flag if successful
Success = True
Private Sub NTService_Stop()
'-- Add code to do what you want to do
' when the service stops
You might also want to add some code in the following events:
- NTService_Pause - for when the service is paused
- NTService_Continue - for when the service is continued
- NTService_Control - for when the service receives a control event other than Start, Stop, Pause, and Continue
We have not addressed the issue issue of what application logic you will put into this service, since that will be up to you. Common methods include using a Timer or launching an ActiveX EXE to do your work for you.
There are a few potential problems when implementing an NT Service in VB 6. Here are some issues to watch out for:
Dependencies - If your service is dependent on other services, you need to make sure this dependency information is set properly in the registry. Warning: improperly setting service dependency information in the registry could make a computer unbootable due to issues like circular dependencies - Service A cannot start before Service B and Service B cannot start before Service A - resulting in neither service ever starting. Be very careful here.
Using RegEdt32 (RegEdit will not work here due to it’s inability to add REG_MULTI_SZ types), go to HKEY_LOCAL_MACHINE\ System\ CurrentControlSet\ Services\ [YOUR SERVICE] and create a new value with a name of DependOnService and a data type of REG_MULTI_SZ. Set the data to the name of the key of the service your NT Service depends on. For example, if your NT Service depends on MSMQ the enter MSMQ since MSMQ is the name of the key in this services branch. If your NT Service depends on multiple services, add each service on its own line. If you are creating distribution media for your NT Service, you can include a .reg file which includes this information (easing deployment efforts).
Threads - since VB is not multithreaded, services written in it can be problematic. Typically, in an NT Service, you would have one thread listening (the listener thread) to the Start, Stop and other commands from the Service Control Manager (SCM) and another thread doing the actual work (the worker thread). Since VB does not support the spawning of threads, we are somewhat limited. If you want to write an NT Service that blocks on an MSMQ queue (waiting for messages to arrive) you will be in trouble, since the thread that is blocking on the queue is not available for responding to the SCM.
Location of EXE - It is important that the executable you created for your NT Service be located on a local drive to the machine on which the NT Service will run. If the executable is on a remote drive, the service will not run throwing Error 5: Access is denied.
Set User Account - Usually you will set the user account of your new NT Service after it is installed. However, you do have the option of setting the user account and password properties on the NTService control at design-time. If you do not set this information, the NT Service will be set to use the Local System account. Make sure that the account you choose has the appropriate security permissions to perform the tasks that you are asking the NT Service to perform. All processing, including calls out to ActiveX EXEs, will use the security context from your NT Service.
Settings - If you will use the registry to store settings for your NT Service, then you should avoid using GetSetting and SaveSetting (since these will use HKEY_CURRENT_USER which will not work since there may be no user logged onto the computer where your NT Service runs). Instead, you should use NTService.GetSetting and NTService.SaveSetting. These work very similarly to the original versions, but will work regardless of who (if anybody) is logged on to the machine.
creating a Windows service in C#.
Writing an NT Service in Visual Basic is certainly possible. There are some inherent problems (not the least of which is threading). However, if you want to accomplish something very simple with an NT Service, VB can work just fine.
You could use .Net (C#, VB.Net, etc.) to work around some of these problems (for example, threading problems). You can read about