Services
Commands for configuring and monitoring Windows services
package require
twapi
This module provides procedures for managing and controlling
Windows services and also allows for writing Windows services in
Tcl.
The commands lock_scm_db, unlock_scm_db and query_scm_db_lock_status allow manipulation of the
Service Control Manager (SCM) database lock during configuration
changes.
The commands get_service_internal_name and get_service_display_name map back and forth between
the internal name and display name of a service.
The command service_exists checks for the existence of a service
while get_service_state returns its state. The commands
get_service_status, get_multiple_service_status and get_dependent_service_status retrieve status
information for one or more services. interrogate_service
can be used to request a service to update its status with the
service control manager (SCM).
Service configuration changes, including creation of new
services and deletion of existing ones, can be done through the
commands create_service, delete_service and set_service_configuration.
The commands start_service, stop_service, pause_service and continue_service control
the run state of a service.
The command run_as_service allows an application to run as a
Windows service. Applications running as services can update their
status with the SCM through update_service_status.
Most commands allow the following options to be specified:
-system SYSTEMNAME |
Specifies the name of the system on which the
command should be invoked. By default, this is the local
system. |
-database DATABASE |
Specifies the service control database to be
operated on. By default, this is the active service control
database on the target system. |
- continue_service INTERNAL_SERVICE_NAME
?options?
- This command resumes the specified service which must be in a
paused state. INTERNAL_SERVICE_NAME must be the
internal name of the service, not the display name. The command
returns 1 if the service has resumed to a running state when the
command completes and 0 otherwise. Note that a return value of 0
does not imply an error, just that the service had not completely
resumed by the time the command returned.
The standard options described in Standard Options may be specified with this
command. In addition, if the option "-wait
MILLISECONDS" is specified the command will wait
until the service is running or until MILLISECONDS milliseconds have expired.
- create_service INTERNAL_SERVICE_NAME
COMMAND ?options?
- This command creates a new Windows service in the service
control manager database.
INTERNAL_SERVICE_NAME is the internal name by
which the service is identified by the service control
manager.
COMMAND contains the system command to be
executed to start the service. This includes the path to the
executable as well as arguments to be passed to it. If the path
contains spaces, it must be specifically quoted else the operating
system will interpret all characters after the first space as
arguments to be passed to the service. For example,
"\"C:\\Program Files\\MyService\\service.exe\" arg1 arg2"
In addition to the Standard Options,
the following additional options may be specified which control
various aspects of the service:
-displayname DISPLAYNAME |
Specifies the user visible name for the service.
This is the name that is shown in the net
start command and the SCM control panel applet. |
-servicetype SERVICETYPE |
Specifies the service type and may have one of the
following values:
win32_own_process |
Service that runs in its own process. This
corresponds to the SERVICE_WIN32_OWN_PROCESS in the Windows SDK
documentation. This is the default if the option is not
specified. |
win32_shared_process |
Service that runs inside a process shared with
other services. This corresponds to the SERVICE_WIN32_SHARED_PROCESS in the Windows SDK
documentation. |
file_system_driver |
File system driver. This corresponds to the
SERVICE_FILE_SYSTEM_DRIVER in the
Windows SDK documentation. |
kernel_driver |
Kernel driver. This corresponds to the SERVICE_KERNEL_DRIVER in the Windows SDK
documentation. |
|
-interactive BOOLEAN |
This option specifies whether the service should be
allowed to interact with the desktop. This is only valid when
-servicetype is specified to be win32_own_process or win32_shared_process. The -account option must not be used with this option since
interactive services must run under the LocalSystem account. |
-starttype STARTTYPE |
Specifies how the service is to be started.
STARTTYPE should have one of the following
values:
auto_start |
The service should be automatically started by the
service control manager during system startup. This is the default
if the option is not specified. |
boot_start |
The service should be automatically started by the
system loader during system boot. This is only valid when -servicetype is specified to be kernel_driver or file_system_driver. |
demand_start |
The service should be started by the system upon
receiving an explicit program request. |
disabled |
The service is disabled and cannot be started even
on program request. |
system_start |
The service is a driver that is started by the
operating system IoInitSystem function during
system initialization. This is only valid when -servicetype is specified to be kernel_driver or file_system_driver. |
|
-errorcontrol ERRORCONTROLMODE |
This option specifies how errors during service
start are to be handled. ERRORCONTROLMODE may
have one of the following values:
ignore |
An error message will be logged to the Windows
event log. The system startup will continue. |
normal |
An error message will be logged to the Windows
event log and a popup displayed to the user. The system startup
will continue. This is the default. |
severe |
An error message will be logged to the Windows
event log. The system startup will continue only if the last known
good configuration is active. Otherwise, the system is restarted
with the last known good configuration. |
critical |
An error message will be logged to the Windows
event log if possible. If the last known good configuration is
active, the system startup is aborted. Otherwise, the system is
restarted with the last known good configuration. |
|
-loadordergroup GROUPNAME |
Specifies GROUPNAME to be the
service load order group to which the service belongs. If the
option is not specified, the service is assumed to not belong to
any load order group. |
-dependencies DEPENDENCYLIST |
Specifies the services and service load order
groups that are required by this service and that must start before
this service. DEPENDENCYLIST is a list of
service names and load order groups. A load order group name must
be prefixed with a + character to
indicate that it is a group name and not a service. |
-account ACCOUNTNAME |
Specifies ACCOUNTNAME to be the
user account under which the service should run. ACCOUNTNAME takes the form domain\username. If the account is a local account,
ACCOUNTNAME may be specified as .\username or username. If this option
is not specified, the service will run under the LocalSystem account. When -servicetype is kernel or
filesystem, ACCOUNTNAME should be the name of the driver object that
the system uses to load the driver. |
-password PASSWORD |
Specifies the password corresponding to the user
account specified in the -account option. This
option is ignored if the -account option is not
specified. |
Example: Install a
service
- delete_service INTERNAL_SERVICE_NAME
?options?
- This command deletes the specified service from the service
control manager database. INTERNAL_SERVICE_NAME
must be the internal name of the service, not the display name. The
standard options described in Standard
Options may be specified with this command.
Example: Uninstall a
service
- get_dependent_service_status INTERNAL_SERVICE_NAME ?options?
- Retrieves the status of services that are dependent on
INTERNAL_SERVICE_NAME and that match a specified
service state. The standard options described in Standard Options may be specified with this
command. In addition, the following options may be specified to
only include services in a given state. If neither of these is
specified, services in all states are included in the returned
list.
-inactive |
Specifying this option will result in inclusion of
services that are in the stopped
state. |
-active |
Specifying this option will result in inclusion of
services that are not in the stopped
state. |
The command returns a list each element of which describes the
status of a single service. The format of the sublist elements is
identical to that returned by the get_multiple_service_status.
Example: Stop and restart a
service
Example: Show the
dependents of a service
- get_multiple_service_status ?options?
- Retrieves the status of multiple services matching the
specified service type and/or state. The standard options described
in Standard Options may be specified
with this command. In addition, the options may be specified to
only include services of a given type and in a given state.
One or more from the following service type options may be
specified to limit the types of services that are included in the
returned list: -kernel_driver, -file_system_driver, -win32_own_process, -win32_share_process, -adapter or
-recognizer_driver. See the description of the
-servicetype option in the create_service command for
the semantics of these values. If no service type options are
specified, all types of services are included in the returned
list.
One of the following options may be specified to limit the returned
services to those in a specific state. If neither of these is
specified, services in all states are included in the returned
list.
-inactive |
Specifying this option will result in inclusion of
services that are in the stopped
state. |
-active |
Specifying this option will result in inclusion of
services that are not in the stopped
state. |
The command returns a list each element of which describes the
status of a single service. The format of the sublist is a list of
the form field1 value1 ... with the following
fields:
attrs |
Contains a list of attributes. Currently, the only
attribute that may appear in this list is systemprocess which indicates that the service runs
in a system process that must alway be running. |
checkpoint |
Contains the last checkpoint value reported by the
service during a lengthy operation. |
controls_accepted |
Contains a bitmask indicating the control commands
accepted by the service. Refer to the Windows SDK documentation for
ControlService for details. |
displayname |
Indicates the user visible name of the service |
exitcode |
The last exit code of the service. If this value is
1066, a service specific error code is returned in the service_code field. |
interactive |
Indicates whether the service is allowed to
interact with the desktop (1) or not
(0). |
name |
Indicates the internal name of the service |
pid |
The PID of the process in which the service is
running. If the service is currently stopped, this will be 0. A
value of -1 indicates that the process id of the service cannot be
determined (NT 4.0). |
service_code |
In case the exitcode
field contains 1066, this field contains a service specific code
stored by the service. |
servicetype |
Indicates the type of the service, and is one of
win32_own_process, win32_share_process, kernel_driver, file_system_driver, adapter, recognizer_driver or an integer denoting the type
if not one of the above. |
state |
Contains the latest reported status of the service
and may have one of the values stopped,
start_pending, stop_pending, running,
continue_pending, pause_pending, paused
or an integer value indicating the status of the service if not one
of the above. |
wait_hint |
Estimated time required to complete an start, stop,
pause or continue operation as last reported by the service. |
Example: Show currently
running Windows services
Example: Show Windows
services that start automatically
- get_service_configuration INTERNAL_SERVICE_NAME ?options?
- This command returns the current configuration data for the
specified service. INTERNAL_SERVICE_NAME is the
internal name by which the service is identified by the service
control manager. The standard options described in Standard Options may be specified with this
command.
The return value is a flat list of the form option1
value1 ... that can be directly passed to the set_service_configuration command. The returned
values depend on which of the following options are specified:
-all |
Returns all option values |
-description |
Returns description of the service if available,
otherwise the empty string. |
-displayname |
Returns the user visible name of the service. |
-errorcontrol |
Returns an indication of how errors during service
startup will be handled. See description of create_service for
details. |
-servicetype |
Returns the service type. See description of
create_service for
details. |
-interactive |
Returns 1 if the
service is allowed to interact with the desktop and 0 otherwise. |
-loadordergroup |
Returns the name of the service load order group to
which the service belongs. |
-dependencies |
Returns a list of names of services and service
load order groups that are required by this service and that must
start before this service. |
-account |
Returns the user account under which the service
runs. |
-starttype |
See description of create_service for details. |
-command |
Returns the command, including the executable name
and parameters, that is invoked to run the Windows service. |
Example: Show Windows
services that start automatically
Example: Show the
services that a specified service depends on
- get_service_display_name SERVICE_NAME
?options?
- This command returns the display name of the specified service.
If SERVICE_NAME is the display name of a
service, it is returned. If it is the internal name of a service,
the corresponding display name is returned. Otherwise, an error is
raised. The standard options described in Standard Options may be specified with this
command.
- get_service_internal_name SERVICE_NAME
?options?
- This command returns the internal name of the specified
service. If SERVICE_NAME is the internal name of
a service, it is returned. If it is the display name of a service,
the corresponding internal name is returned. Otherwise, an error is
raised. The standard options described in Standard Options may be specified with this
command.
- get_service_state INTERNAL_SERVICE_NAME
- Returns the last reported state of the service. See the
description of the state field for the
command get_service_status for possible values.
- get_service_status INTERNAL_SERVICE_NAME ?options?
- This command returns the latest status information sent by the
given service to the service control manager. The standard options
described in Standard Options may be
specified with this command. The return value is a flat list of the
form field1 value1 .... The following fields are
returned:
attrs |
Contains a list of attributes. Currently, the only
attribute that may appear in this list is systemprocess which indicates that the service runs
in a system process that must alway be running. |
controls_accepted |
Contains a bitmask indicating the control commands
accepted by the service. Refer to the Windows SDK documentation for
ControlService for details. |
exitcode |
The last exit code of the service. If this value is
1066, a service specific error code is returned in the service_code field. |
interactive |
Indicates whether the service is allowed to
interact with the desktop (1) or not
(0). |
servicetype |
Indicates the type of the service, and is one of
win32_own_process, win32_share_process, kernel_driver, file_system_driver, adapter, recognizer_driver or an integer denoting the type
if not one of the above. |
state |
Contains the latest reported status of the service
and may have one of the values stopped,
start_pending, stop_pending, running,
continue_pending, pause_pending, paused
or an integer value indicating the status of the service if not one
of the above. |
service_code |
In case the exitcode
field contains 1066, this field contains a service specific code
stored by the service. |
checkpoint |
Contains the last checkpoint value reported by the
service during a lengthy operation. |
wait_hint |
Estimated time required to complete an start, stop,
pause or continue operation as last reported by the service. |
pid |
The PID of the process in which the service is
running. If the service is currently stopped, this will be 0. A
value of -1 indicates that the process id of the service cannot be
determined (NT 4.0). |
- interrogate_service
INTERNAL_SERVICE_NAME ?options?
- This command asks the specified service to update the service
control manager with its current status. INTERNAL_SERVICE_NAME must be the internal name of the
service, not the display name. The standard options described in
Standard Options may be specified
with this command.
- lock_scm_db ?options?
- This command locks the service control manager database and
returns a handle to the lock. The handle must later be released by
passing it to unlock_scm_db. The standard
options described in Standard
Options may be specified with this command.
- pause_service INTERNAL_SERVICE_NAME
?options?
- This command pauses the specified service. INTERNAL_SERVICE_NAME is the internal name of the
service, not the display name. The command returns 1 if the service
is paused when the command completes and 0 otherwise. Note that a
return value of 0 does not imply an error, just that the service
had not completely changed to a paused state by the time the
command returned. A Tcl error is generated if the service was not
running.
The options described in Standard
Options may be specified with this command. In addition, if the
option "-wait MILLISECONDS"
is specified the command will wait until the service is paused or
until MILLISECONDS milliseconds have
expired.
- query_scm_db_lock_status v_lockinfo
?options?
- This command returns the state of a service control manager
database lock. It returns 1 if the database is locked and 0
otherwise. The user name of the lock holder and the number of
seconds that the lock has been held is returned as a list in the
variable referenced by v_lockinfo. The options
described in Standard Options may be
specified with this command.
- run_as_service SERVICES ?-interactive BOOLEAN?
- This command sets up the mechanisms that allow a Tcl
application to act as a Windows service. It must be only called
when the application is started by the Windows SCM as a Windows
service, else it will fail silently.
SERVICES is a list of SERVICENAME
HANDLER pairs that describe the services that will run in the
process. Note a single process may host multiple services.
SERVICENAME is the internal name of a service.
HANDLER is a script that will be invoked for
that service in response to various state changes as described
below. The option -interactive indicates whether
the services running in the application will require interaction
with the desktop.
When the application is started by the SCM, it should perform its
basic application-wide initialization and then call run_as_service. The
command will then set up the communication mechanisms with the SCM
and register the specified services. The control signals sent by
the SCM to the service are passed on to the HANDLER script registered for the service by the
application.
There are four main controls sent by the SCM to control the state
of a service. These correspond to the tokens start, stop,
pause and continue. For each of these, HANDLER is invoked with four additional arguments. The
first is control token itself. The second is the name of the
service for which the control was sent and should match (ignoring
case) one of the SERVICENAME values passed to
run_as_service. The third argument is a sequence
number (more on this later). The fourth argument is a numeric value
that is the actual value of the control signal sent by the
SCM.
In response to a control signal, the handler must take whatever
action necessary and then notify the SCM by calling update_service_status, passing it the process state.
For example, in response to a pause
control, the application may take whatever actions required to
temporarily pause the service operation and then respond by passing
the paused state to update_service_status. Alternatively, if the service
cannot be paused for whatever reason, it may respond by passing the
state running. Refer to update_service_status for details on valid
responses.
The application must respond to every control notification with a
corresponding call to update_service_status. There is no hard time limit
during which this call must be made but it is a good idea not to
delay the response too long. update_service_status can be either invoked from the
handler itself or scheduled at some later point after the necessary
actions have been taken by the application. During this time, TWAPI
may internally send responses to the SCM essentially asking it to
keep waiting for an answer without timing out.
Because multiple controls may be received from the SCM before
previous controls have been fully processed, and to allow for
asynchronous responses from the application, a sequence number is
passed as the third argument to the callback. When the application
responds using update_service_status, this sequence number should be
passed to the call. When responses are made out-of-order, those
with older sequence numbers will be ignored.
In addition to the above notifications that deal with the state
changes for the service, the handler may be sent two additional
controls: userdefined and all_stopped. The userdefined control is strictly
application-dependent and not used by the SCM. User defined
controls can be sent to a service using command line utilities such
as the Windows sc program. The arguments passed
to the handler are the same as described above. The fourth
argument, the numeric value of the control, will be in the range
128-255 and can be used by the application to distinguish between
different signals. Note that the application does not need to call
update_service_status in response to a userdefined control.
The all_stopped control is sent when
all services in the process have been stopped. The application
should normally clean up and exit when this control is received.
The remaining arguments passed to the handler are either empty
strings or 0 and are not used.
- service_exists SERVICE_NAME ?options?
- This command returns 1 or 0 depending on whether a service with
the specified name exists or not. SERVICE_NAME
may be either the internal name of the service or the display name.
The options described in Standard
Options may be specified with this command.
- set_service_configuration INTERNAL_SERVICE_NAME ?options?
- This command allows modification of configuration data for the
service specified by INTERNAL_SERVICE_NAME. In
addition to the options described in Standard Options, the following options may
be specified to set configuration data. The values for any
unspecified options will remain unchanged.
-displayname DISPLAYNAME |
Specifies the user visible name for the service.
This is the name that is shown in the net
start command and the SCM control panel applet. |
-command COMMAND |
COMMAND contains the system
command to be executed to start the service. See description of
create_service for
details. |
-servicetype SERVICETYPE |
Specifies the service type. See description of
create_service for
details. |
-interactive BOOLEAN |
This option specifies whether the service should be
allowed to interact with the desktop. See description of this
option in command create_service for details. |
-starttype STARTTYPE |
Specifies how the service is to be started. See
description of this option in command create_service for valid
values for STARTTYPE. |
-errorcontrol ERRORCONTROLMODE |
This option specifies how errors during service
start are to be handled. See description of this option in command
create_service for
valid values for ERRORCONTROL. |
-loadordergroup GROUPNAME |
Specifies GROUPNAME to be the
service load order group to which the service belongs. If the
option is not specified, the service is assumed to not belong to
any load order group. |
-dependencies DEPENDENCYLIST |
Specifies the services and service load order
groups that are required by this service and that must start before
this service. See description of this option in command create_service for
details. |
-account ACCOUNTNAME |
Specifies ACCOUNTNAME to be the
user account under which the service should run. See description of
this option in command create_service for details. |
-password PASSWORD |
Specifies the password corresponding to the user
account specified in the -account option. This
option is ignored if the -account option is not
specified. |
Example: Change a Windows
service account
- start_service INTERNAL_SERVICE_NAME
?options?
- This command starts the specified service if it is not already
running. INTERNAL_SERVICE_NAME must be the
internal name of the service, not the display name. The command
returns 1 if the service is up and running when the command
completes and 0 otherwise. Note that a return value of 0 does not
imply an error, just that the service had not completely started by
the time the command returned.
The options described in Standard
Options may be specified with this command. In addition, if the
option "-wait MILLISECONDS"
is specified the command will wait until the service is running or
until MILLISECONDS milliseconds have
expired.
Example: Stop and restart a
service
- stop_service INTERNAL_SERVICE_NAME
?options?
- This command stops the specified service if it is currently
running. INTERNAL_SERVICE_NAME must be the
internal name of the service, not the display name. The command
returns 1 if the service has stopped by the time the command
completes and 0 otherwise. Note that a return value of 0 does not
imply an error, just that the service had not completely stopped by
the time the command returned.
The options described in Standard
Options may be specified with this command. In addition, if the
option "-wait MILLISECONDS"
is specified the command will wait until the service is stopped or
until MILLISECONDS milliseconds have
expired.
Example: Stop and restart a
service
- unlock_scm_db SCM_LOCK_HANDLE
- This command releases a lock previously obtained through
lock_scm_db.
- update_service_status
SERVICENAME SEQNO STATE ?options?
- This command should be called by applications, running as a
Windows service, to update their status information with the
Windows service control manager (SCM). The command may be called
asynchronously at any time, but is most often called in response to
a control notification from the SCM requesting a state change. See
run_as_service for
more detail.
SERVICENAME is the name of the service whose
status is being updated.
SEQ is the sequence number of the control
notification to which this is the response. See the discussion in
the run_as_service
documentation. If the call is not in response to a control
notification, SEQ should be set to 0.
STATE is the of the application and should be
one of the values stopped, running or paused. Note
that an application can stop at any time, but should not generally
change state to running or paused on its own without a control notification
from the SCM. Doing so will in all likelihood confuse the SCM
manager sufficiently to make the service unmanageable.
If the service state being specified is stopped, the application may also indicate a
standard Windows exit code and a service-specific exit code by
specifying their values through the options -exitcode and -servicecode
respectively.
Copyright © 2003-2008 Ashok P. Nadkarni