Services

Commands for configuring and monitoring Windows services

SYNOPSIS

package require twapi
continue_service INTERNAL_SERVICE_NAME ?options?
create_service INTERNAL_SERVICE_NAME COMMAND ?options?
delete_service INTERNAL_SERVICE_NAME ?options?
get_dependent_service_status INTERNAL_SERVICE_NAME ?options?
get_multiple_service_status ?options?
get_service_configuration INTERNAL_SERVICE_NAME ?options?
get_service_display_name SERVICE_NAME ?options?
get_service_internal_name SERVICE_NAME ?options?
get_service_state INTERNAL_SERVICE_NAME
get_service_status INTERNAL_SERVICE_NAME ?options?
interrogate_service INTERNAL_SERVICE_NAME ?options?
lock_scm_db ?options?
pause_service INTERNAL_SERVICE_NAME ?options?
query_scm_db_lock_status v_lockinfo ?options?
run_as_service SERVICES ?-interactive BOOLEAN? ?-controls CONTROLLIST?
service_exists SERVICE_NAME ?options?
set_service_configuration INTERNAL_SERVICE_NAME ?options?
start_service INTERNAL_SERVICE_NAME ?options?
stop_service INTERNAL_SERVICE_NAME ?options?
unlock_scm_db SCM_LOCK_HANDLE
update_service_status SERVICENAME SEQNO STATE ?options?

DESCRIPTION

This module provides procedures for managing and controlling Windows services and also allows for writing Windows services in Tcl.

Service Configuration and Monitoring

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.

Writing services in Tcl

The command run_as_service allows an application to run as a Windows service. Services are implemented as callback handlers that are invoked in response to control signals received from the system. These signals include controls to stop the service, to pause and continue, or may be notifications of events such as session changes. The list of such signals and their handling is detailed in run_as_service.

While running as a service, applications need can update their status with the SCM, either asynchronously or in response to control signals. This can be done through update_service_status.

Standard Options

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.

Commands

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? ?-controls CONTROLLIST?
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. The command does not return until the service is ready to exit. Rather, it invokes the service handlers that implement each service in response to notifications received from the system as described below.

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 system notifications as described below.

The option -interactive indicates whether the services running in the application will require interaction with the desktop.

The option -controls configures what controls messages from the system, signals and notifications, are understood by the services. The SCM will restrict itself to sending only these although for robustness it is recommended that all services gracefully handle all signals as described below. Note that it is not possible to specify different values for this on a per-service basis. By default, CONTROLLIST includes control signals stop and shutdown. Note the notification start is implicit and must be handled by every service.

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.

The messages sent to a service fall into two categories - control signals and notifications. Control signals generally require the service to take some action, often a state change such as stopping or pausing the service. Notifications are generally of an informational nature to apprise the service of some system event such as session changes or power events.

There are five controls signals sent by the SCM to control the state of a service. These correspond to the tokens start, stop, shutdown, pause and continue. For each of these, HANDLER is invoked with four additional arguments. The first is control signal token itself. The second is the name of the service for which the control was sent and should match (ignoring case) the corresponding 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.
start Sent to start the service.
stop Sent to stop the service.
pause Sent to pause the service without terminating it. This is only received if pause_continue has been specified as an element in the -controls option.
continue Sent to contiue a service that was previously paused. This is only received if pause_continue has been specified as an element in the -controls option.
shutdown Sent to indicate the system is shutting down. Should be treated similar to stop.
interrogate Sent to enquire about the service status. TWAPI handles this internally and never actually sends this to the application.


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 new 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. It is very important to correctly notify the service control manager of the state change.

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 control signals that may be sent by the SCM, it may also send notifications to the service to inform it of system events. These are passed on to the appropriate service callback handler in the same fashion as the control signals. Unlike for control signals, the application need not, and generally should not, respond with a call to update status.

In addition to the four arguments described for control signals, some notifications may have additional arguments. The various notifiations are shown in the able below.
all_stopped The all_stopped notification is sent to the last running service in the application when all other 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 should not be used. This notification is internally generated by TWAPI and not sent by the system.
hardwareprofilechange Notifies the application that the system hardware profile has changed. This is only received if paramchange has been specified as an element in the -controls option.
paramchange Notifies the application that one of its configuration parameters has changed and it should re-read its service information from the Windows registry. This is only received if paramchange has been specified as an element in the -controls option to indicate to the service manager that the service can read and change its configuration while running.
netbindadd Refer to the Windows SDK. This is only received if netbindchange has been specified as an element in the -controls option.
netbinddisable Refer to the Windows SDK. This is only received if netbindchange has been specified as an element in the -controls option.
netbindenable Refer to the Windows SDK. This is only received if netbindchange has been specified as an element in the -controls option.
netbindremove Refer to the Windows SDK. This is only received if netbindchange has been specified as an element in the -controls option.
powerevent This notifies the application of a change in the power status of the system. This is only received if powerevent has been specified as an element in the -controls option. In addition to the standard arguments, an additional argument is appended detailing the nature of the change. This may be one of apmsuspend, apmstandby, apmresumecritical, apmresumesuspend, apmresumestandby, apmbatterylow, apmpowerstatuschange, apmoemevent, or apmresumeautomatic.
sessionchange Notifies that a session change event has occurred. This is only received if sessionchange has been specified as an element in the -controls option. In addition to the standard arguments, two additional arguments are appended. The first of these indicates the nature of the session change and is one of console_connect, console_disconnect, remote_connect, remote_disconnect, session_login, session_logoff, session_lock, session_unlock or session_remote_control.

The second additional argument is the session identifier for which the event is being reported.
user_defined 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 standard four arguments are passed on except that the fourth argument, the numeric value of the control, will vary within the range 128-255 and can be used by the application to distinguish between different signals.


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

Copyright © 2003-2008 Ashok P. Nadkarni

Tcl Windows API 2.2.3 Privacy policy