Trigger-start services are an efficiency
measure in Windows 7. The short story is that Windows currently uses
too many resources because as user needs change it needs to support
more and more software. One of the most common problems is too many
services. Most services remain running while you work with Windows. The
service constantly polls the system looking for work to do. Of course,
this polling process wastes processing cycles. In addition, the service
constantly uses resources such as memory because it must remain loaded
at all times. Even though developers don't often use the service-start
modes effectively, you do have several options for starting and
stopping standard services.
Disabled:
The service is completely disabled and can't start on its own. However,
a user can manually start the service as required using either the
Services applet in the Control Panel or the Service Control (SC)
command line utility.
Manual:
The operating system can start the service when it detects a need, or
an application can start the service through a request. While the
service is stopped, it doesn't use any system resources or processing
cycles.
Automatic:
The service starts during system startup. This is the mode most
developers use. Unfortunately, not every service needs to start
immediately (and sometimes they don't need to start at all). Overuse of
this mode is the reason Microsoft has developed trigger-start services.
Windows start times constantly increase, in part, because of the use of
automatic mode when a service doesn't actually require it.
Automatic Delayed:
Microsoft introduced this mode with Windows Vista as a sort of
compromise. The service still starts automatically, but it waits until
Windows is completely running to do so. The user can begin working with
Windows faster, and the perception is that Windows starts faster.
Because this is a newer mode, few developers use it, and use of this
mode doesn't solve the basic problem with automatic mode — overuse of
system resources and processing cycles.
Because few developers actually use manual or
disabled mode, Microsoft had to come up with something different —
something that developers would understand and use. In addition,
developers have requested something more flexible than the four simple
modes currently supported by standard services. A trigger-start service
is akin to a manual standard service, except that it relies on the
operating system to wake it up when a special event occurs. It's the
use of a special event that makes trigger-start services more flexible
than standard services. Using a trigger-start service means that the
service uses processing cycles and resources only when there's
something to do, making the service considerably more efficient. The
following sections describe trigger-start services in more detail.
NOTE
The example in this section relies on Platform
Invoke (P/Invoke) to perform its task. Many developers dislike using
P/Invoke because the code can be hard to read and even harder to
understand. Normally, Microsoft or a third party will create a library
to make Win32 API access easier, but such a library isn't available for
working with trigger-start services at the time of this writing. If you
hear of such a library, feel free to contact me about it at JMueller@mwt.net.
1. Triggering a Service
A trigger-start service isn't anything too strange.
Don't think of it as an entirely new technology. Rather, it's simply a
new way to start the service when needed. If you focus on the means of
starting the trigger-start service, you'll find the entire process
easier to understand. A trigger-start service can use any of these
triggers as a source for starting:
Adding or removing a device:
Fires whenever the system sees a new device. For example, the user
could attach a Universal Serial Bus (USB) device, such as a camera.
This event also fires when a device is removed from the system, so you
could handle a situation where the user attaches a printer, prints
something, and then detaches the printer.
Joining or leaving a domain:
Fires whenever the system logs in to a domain or logs out of a domain.
You can use this event to monitor the user's activities with servers.
Opening or closing a firewall port:
Fires whenever the system detects the opening or closing of a firewall
port. A service that relies on this trigger could monitor application
use of temporary Internet access. It could also look for unusual
activities, such as those performed by viruses.
Changing a group policy:
Fires whenever anyone modifies a group policy on the system, even if
the modification is automatic (such as through a login script). A
service using this trigger could look for unusual activities or simply
respond to changes in user rights.
Changing network availability:
Detects changes in the network configuration. For example, this trigger
will detect when the first IP address for a TCP/IP stack becomes
available. It also detects when a TCP/IP stack is no longer available
(or is about to become unavailable), so that applications can terminate
communication that relies on the TCP/IP stack.
Defining a custom event using Event Tracing for Windows (ETW):
Allows the developer to create custom event triggers. A custom event
trigger could use any event you desire. For example, you might want to
start the service only when an external utility makes a request. You
could create a custom trigger to start the service when the system
detects such a request. Generally, it's far easier to use manual or
disabled mode whenever possible instead of creating a custom trigger.
NOTE
Some trigger-start service methods are thwarted
by third-party software. For example, if the user installs a
third-party firewall and disables the Windows firewall, it's unlikely
trigger-start services that rely on the opening or closing of a port
will work. This particular trigger relies on the Windows Firewall to
detect changes in port configuration. It's not likely that third-party
vendors will add the required support to their firewalls unless
Microsoft mandates the change as part of a conformance criterion.
In order to create a trigger, you must provide the
operating system with the information it needs to detect the event and
then start the appropriate service. A trigger description consists of
the following pieces of information:
Trigger event type: The major type of the trigger event, as previously described in this section.
Trigger event subtype:
A subtype that better describes the trigger event. Not all trigger
types have subtypes. For example, there aren't any subtypes associated
with joining or leaving a domain, but there are subtypes associated
with adding or removing a device (in this case, you supply the
Universally Unique Identifier, or UUID, of the device).
Action: The task to perform when the event occurs. In general, the trigger either stops or starts a service.
Data:
Information to provide to the service as part of the action. The data
you supply depends on the trigger event type, subtype, and action. Some
trigger types don't require any additional data. For example, a trigger
based on the opening of a port requires that you specify the port
number, but joining or leaving a domain doesn't.
Windows supplies two methods of registering a
trigger-start service. The first technique is to use the SC utility
with the TriggerInfo command. For example, if you want to set the
example service to start when it detects a change in Port 23 using the
TCP protocol, you type SC TriggerInfo TriggerStartService Start/PortOpen/23;TCP and press Enter. Let's take that command apart.
SC is the name of the utility.
TriggerInfo is the command that defines a trigger-start service.
TriggerStartService is the name of the example service (not the display name, but the actual service name).
Start is the action you want Windows to perform.
PortOpen is the trigger event type (port) and subtype (open).
23;TCP is the data for the trigger — Port 23 and the TCP protocol.
Unfortunately, the manual technique doesn't work
well because it relies on the administrator to know about the
TriggerInfo command and manually register the service after
installation. The second technique is to programmatically register the
service as a trigger-start service. In this case, the installation
routine automatically provides the required trigger-start information
to the operating system. The problem with this approach is that you
must work with P/Invoke to use it. In short, there aren't any easy
methods for creating a trigger-start service using managed code, but
you can do it.
2. Obtaining the ServiceNative.CS File
As previously mentioned, there's currently no
third-party library or direct .NET Framework support for trigger-start
services. However, Microsoft does supply the Knowledge Base article at http://support.microsoft.com/kb/975425. When you download the sample provided as part of the Knowledge Base article, you get some code and a confusing ReadMe.TXT file that doesn't really help you understand how trigger-start services work.
The example also includes the ServiceNative.CS
file (when you download the C# version of the example; you can also
download Visual Basic and C++ versions of the example). This file has
useful code in it that makes the job of creating a trigger-start
service significantly easier. You still have to deal with P/Invoke, but
at least you don't have to create all the data structures from scratch.
In addition, the ServiceNative.CS file correctly defines the AdvAPI32.DLL calls used to create a trigger-start service.
Because the ServiceNative.CS file is so
helpful, the example in this section relies on it to reduce the amount
of code you must write. Download the C# version of the example to your
hard drive. Double-click the resulting CSWin7TriggerStartService.EXE file and follow the prompts to place the example on your hard drive in a location that you can easily find later.