|
Programmatic Support for Windows NT Services
Note that wherever this document refers to Windows NT, the comments apply to both Windows NT 4, Windows 2000, and later versions, unless stated otherwise. Windows NT and Windows 2000 provides support for special programs called services. NT services run in the background, usually without direct user interaction, often started automatically at some point in the boot process. They typically run under the special LocalSystem account which means that they do not need to be associated with a username and password. (This also places some security restrictions on what services can do by default.) Services are analogous to Unix "daemons," but formalised into the operating system. This formal role of NT services brings some advantages to the system administrator. For example, they can be configured to start automatically at various points in the boot process, or can be controlled - locally or remotely - using NET START, Control Panel Services or programs such as ServPanel. The downside of this is that ordinary programs will not run as NT services. A service program needs to establish and maintain contact with the NT Service Control Manager) (SCM. This requires special coding endemic to the program: if a service does not maintain contact with the SCM, NT assumes it has failed and shuts it down. As an alternative to writing special code, the Windows NT Resource Kit provides a utility called SRVANY.EXE'. SRVANY.EXE will start an ordinary program in the context of an NT service. However it is pretty limited and does not address some of the constraints of NT Services:
Because of these limitations I wrote two utilities, SVC and SRVSTART. SVC allows you to install, modify or remove Windows NT services. SRVSTART allows you to run executable programs as if they were services.
Between them they give you far greater management and flexibility than is provided by the Windows NT and the NT Resource Kit.
This article is Copyright (C) 2000 - 2007 Nick Rozanski.
SVC and SRVSTART are distributed under the terms of the
GNU General Public License as published by the Free Software Foundation (675 Mass Ave, Cambridge, MA 02139, USA)
They are distributed in the hope that they will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
This article applies to the following versions of software:
You can check the version of the SRVSTART DLL or executable by running the following shell command against it (new in version 1.1): find "***" srvstart.dll find "***" srvstart.exe You will see output similar to the following: *** SRVSTART version 1.10 Copyright (C) 1998 - 2000 Nick Rozanski (##############)
SRVSTART is a rewrite (in C++) of an earlier version of the program called SYBSTART.
The new version contains a number of enhancements and extra features.
SVC is a simple command-line utility which allows you to install, modify or remove Windows NT Services
SVC runs on Windows NT (not 95 or 98). To run it you require the following files somewhere in your PATH.
Both of these components are available from my website.
To run SVC, type svc.exe at a console prompt.
SVC has the following actions:
SVC will prompt you for all responses. At any point you can type ? (question mark) for a short explanatory help message. If you are having trouble running SVC, you can try running svc.exe -d. This prints out internal SVC debug messages as it runs.
If you don't like SVC's command-line interface, I recommend
ServPanel from Ballard Software.
This is an easy-to-use GUI utility which allows you to install and modify services,
and the latest version has pretty much all the install functionality of SVC.
It also has a very nice interface for starting and stopping services individually or in groups.
Because modifying services is a potentially destructive activity, SVC is deliberately restricted in what it can do. A service to be installed, modified or removed must have the following characteristics:
These restrictions are present for your own safety!
Modify Windows NT service settings at your own peril. Making incorrect changes can render Windows NT unuseable.
If you don't know what you are doing, don't mess about with services!
Version 1.0 (30 June 1998)
First release version.
SRVSTART is a Win32 executable and DLL which allows you to run commands as if they were Windows NT services. It also has some features to enhance the running of ordinary console commands (prompting for parameters etc). You can also use SRVSTART to install or remove a service which is based on the SRVSTART.EXE executable (new in version 1.1).
You can find a Services Quick Start Guide at http://www.nick.rozanski.org.uk/services_quick.
SRVSTART runs on Windows NT, 2000, 2003 and XP. To run it you require the following files somewhere in your PATH.
All of these components are available from my website.
At run time, SRVSTART operates in one of two modes.
Support for installing and removing services is described
later.
Use the following syntax to run a program in command mode. srvstart cmd window_title [ options ... ] program [ program_parameters ... ]
4.2.2 Service ModeUse the following syntax to run a program in service mode. srvstart [ svc ] service_name [ options ... ] program [ program_parameters ... ]
4.2.2.1 NoteThe srvstart syntax is never entered at the command line. Rather, use this syntax as the command line when installing a service (eg in response to SVC's Enter binary path name prompt).
For testing, you can supply the keyword any instead of cmd or svc.
This will attempt to run the program as a service (keyword svc)
and if this fails run it as a console command (keyword cmd).
SRVSTART does the following.
4.4 OptionsThe following SRVSTART options apply to command and service modes.
The following SRVSTART options apply to command mode only.
The following SRVSTART options apply to service mode only.
Options -s, -p, -q, -l and -e control the environment in which the program runs. If no -p option is given, a default path of the form: %SYBASE%\install;SYBASE%\bin;%SYBASE%\dll;%SystemRoot%;%SystemRoot%\system32 is used. (%SystemRoot% is the Windows NT root directory, eg C:\WINNT). The -q option assigns a path as above, but using the value supplied to -q, instead of %SYBASE%. For example, -q C:\NEWSYB would assign a path of the form C:\NEWSYB\install;C:\NEWSYB\bin;... etc. Environment values which contain embedded environment variables will have these substituted, but only if they are already defined. For example: ... -e myvar1=myvalue1 -e myvar2=my_%myvar1%_val ... will set myvar1 to myvalue1 and myvar2 to my_myvalue1_val. However ... -e myvar2=my_%myvar1%_val -e myvar1=myvalue1 ... will set myvar2 to my_%myvar1%_val (since myvar1 is not defined at this point.
Note that in service mode,
the only environment variables available when SRVSTART starts are the system
environment variables.
(These are the environment variables in the upper list box in In Control Panel|System|Environment.)
If the service is started using a named Windows NT account, then the environment for that account will also available.
Options -d, -o, and -h control SRVSTART debugging.
Note that you must use the Debug executables for level 2 (you can find these in the Debug directory of the full distribution). -o target causes debug messages to be sent to target.
By default, SRVSTART logs error messages to the Event Log in service mode, and to stdout otherwise.
-h displays help information and exits.
(The other SRVSTART parameters need not be supplied in this case.)
-x specifies the priority at which the program should run.
It is ignored in command mode unless -w is supplied.
In command mode, -w opens a new console window to run the program,
and -m opens this window minimised.
These options are ignored in service mode.
If the -y seconds option is specified, SRVSTART waits this number of seconds before reporting to the Windows NT Service Control Manager that the service has started. Use this option if the command takes a long time to initialise (default zero).
In service mode, SRVSTART regularly checks the process it has started to see if it is still running.
If it has finished, then SRVSTART reports a "service stopped" status to the Service Control Manager and then exits.
The -t seconds option defines how often this check is done (default every second).
-c controlfile specifies that SRVSTART should get its options from controlfile. This is a text file with one option per line. Options are grouped in sections, with the section name (which is the window or service name) in square brackets. Options before any section apply to all commands. All section lines are of the form [service_or_window_name]. All option lines are of the form keyword=value. Blank lines, and comments lines (starting #) are ignored. For example: # comment keyword=value ... [service_or_window_name_1] keyword=value keyword=value ... [service_or_window_name_2] keyword=value ... SRVSTART reads the control file, applying all keywords before the first section. It then finds the section whose name matches the supplied window or service name, and applies all keywords in that section. When a control file is used, the program and program_parameters can be omitted from the command line. Note that SRVSTART applies environment variable substitution to all keyword values which are filenames, pathnames or directories (new in version 1.1). For this to work, the environment variable must already be defined (either globally to Windows NT or using the env directive) at the time that the directive is read. For example, the directive debug_out=%TEMP%\myservice.out will log debug output to the file myservice.out in the Windows temporary directory (usually C:\TEMP).
You must provide a startup directive for each service which starts using a control file.
All other directives are optional.
The following keywords replace the SRVSTART command-line options.
The following keywords are used to define SRVSTART commands. Apart from startup they have no command-line equivalents.
The following keywords assign drive mappings.
The command to run, program [ program_parameters ] may be any executable program, that is anything with extension .com, .exe or .bat. program and program_parameters may refer to environment variables using the %var% syntax. These will be substituted (not recursively) where encountered, for example %HOME%\bin\mycommand.exe %SYSTEMROOT%.
For command mode, if the -w flag is not supplied, the command can also be a DOS command (eg dir).
For command mode, parameters may include substitution text of the form:
{prompt}
{prompt:default}
Here, SRVSTART displays the prompt on stdout and reads from stdin, substituting the entered text for everything between { and }. If the user just presses return, then default will be used (if supplied). Either default or prompt can be empty strings. If prompt or default include a space or other symbol meaningful to the NT "shell", surround them in double-quotes. If prompt begins with a - (hyphen) then the text entered by the user will not be echoed back to the terminal (for passwords etc). For example:
send_server.exe -s{server:MYSERV} -u{user name} -p{-password}
This will result in the following interaction: server [MYSERV]: enter server name here or press return for MYSERV user name: no default password: response will not be echoed to screen You can use SRVSTART itself to install or remove services that are based on the SRVSTART.EXE executable (new in version 1.1). The syntax is as follows.
The service which is installed has the following characteristics.
Note that the remove option will remove any service, not just one installed using SRVSTART. It does not prompt for confirmation.
As can be seen this support is quite simple - if you need more powerful management of services then consider using SVC.
There is no support at present for pausing or resuming the service. SRVSTART will ignore pause or resume requests from the Service Control Manager. SRVSTART does not extensively validate things supplied to it on the command line or in the control file. A bad invocation can sometimes cause it to core dump. SRVSTART is pretty relaxed in its error-checking of things like new. Failure here should become obvious pretty quickly.
In command mode when the -w flag is not supplied,
it would be very useful if SRVSTART changed the window title (so you could see it in the taskbar).
I can't work out how to do this.
Version 1.0 (31 March 2000) First release version. (Rewritten as a DLL and executable in C++ from SYBSTART with some new functionality.) Version 1.1 (30 June 2000)
5 SRVSTART.DLL - Windows NT Service Support LibraryThe SRVSTART DLL on its own provides all of the service management features of SRVSTART to programs written in C++.
This allows you to write your own NT services, making just a few simple calls to manage the service's interactions with the SCM.
The SRVSTART library runs on Windows NT. _95_SUPPORT To run it you require the following files somewhere in your PATH at runtime.
At compile/link time, you will need the following:
All of these components are available from my website.
Further information on building programs to use the DLL is given below.
The SRVSTART library exports the following classes.
5.3 Class: CmdRunnerCmdRunner is used to start an external program (command or service mode) within a defined environment. The following examples show how to use CmdRunner to run a command in the same or another process.
5.4 Class: ScmConnectorScmConnector is used to manage the interaction between a service program and the Windows NT Service Control Manager. The following examples show how to use ScmConnector in a service program.
5.4.1 ScmConnector Stop HandlersYou must install a stop handler for your ScmConnector object. This will be activated by the ScmConnector if the service receives a STOP request from the Service Control Manager. If you don't do this then it will not be possible for the Service Control Manager to stop your service. There are three ways to do this.
Whichever method you choose, you must ensure that if the callback is activated, your service program will shut itself down. Timing is crucial with service programs. In particular, the program must connect to the SCM within one second of startup, or Windows NT assumes it is invalid. To ensure this, you should make sure that you create the ScmConnector object early in your program (preferably right at the start). Once you do this, ScmConnector will make the appropriate status notifications to the Service Control Manager for you. Furthermore, a service program must respond promptly to requests from the Service Control Manager (specifically, "interrogate" and "stop" requests). ScmConnector handles this for you automatically once it has been instantiated. It runs in its own thread (two threads, actually) and you do not need to take any special actions other than to notify it when your status changes (when you are shutting down).
These constraints aside, there are no restrictions on the time that a service can take to start or stop.
However ScmConnector will log an informational message if startup takes more than a minute.
In general, methods respond to errors by raising a C++ exception. All methods which can throw an exception are defined using the following syntax: class::method(parameters...) throw (SrvStarterException); This syntax is not supported by Microsoft C++ (they claim it is non-standard) but I have included it to denote the methods which can throw exceptions. Note that most constructors fall into this category. All exceptions are of class SrvStart::SrvStarterException, defined in SrvStart.h. (SrvStart is the namespace here.) Some of the key public data members of this class include: SRVSTART_EXCEPTION exceptionId; char className[SRVSTART_EXCEPTION_STRING_SIZE]; char methodName[SRVSTART_EXCEPTION_STRING_SIZE]; char errorMessage[SRVSTART_EXCEPTION_STRING_SIZE]; char sourceFile[SRVSTART_EXCEPTION_STRING_SIZE]; int lineNumber;
Your calling program should catch these exceptions and interrogate the thrown object for further information.
The library implements any mode as follows. When creating your ScmConnector object, set the paramter allowConnectErrors to true. Then check the status of the service. #include
If status is STATUS_MUST_START_AS_CONSOLE then
the ScmConnector failed to connect to the Service Control Manager.
No exception will be raised in this case.
The following should be taken into account when building software using the DLL.
If you want to include debug code in your service then why not use my logger.dll?
This provides a simple interface for logging error, information and debug messages
to a variety of targets including stdout, text files or
the Windows NT Event Log.
Check out my website for details.
There is no support at present for pausing or resuming the service.
ScmConnector will ignore pause or resume requests from the Service Control Manager.
Version 1.0 (31 March 2000) First release version. (Rewritten as a DLL and executable in C++ from SYBSTART with some new functionality.) Version 1.1 (30 June 2000)
Enhanced existing classes, and created simple new class ServiceManager,
to support new functionality described above.
SVC and SRVSTART are issued under the terms of the GNU General Public License'. SVC and SRVSTART are built using Microsoft Visual C++. I have not used any non-standard features (as far as I am aware) so the source should compile under any C++ compiler for Windows NT. (I haven't tried this.)
Full source code for the executables and DLL is available.
I welcome feedback and comments on these programs. You can email me for support, although I can't guarantee to give any. Please note that the Sybase features in SVC and SRVSTART are only included for backwards compatibility and may not be maintained in the future. (I left Sybase several years ago.) |
| Copyright © 2007 Nick Rozanski | URL: http://www.nick.rozanski.org.uk/index.php?page=services | Last changed: 5 July 2008 |