Step 3: Handling Control Requests
In Step 2, you used the ServiceMain function to register the control handler function. The control handler is very similar to the window callback function that processes various Windows messages. It checks what request was sent by the SCM and acts accordingly.
Each time you call the SetServiceStatus function, you must specify that the service accepts the STOP and SHUTDOWN requests. Listing 2 shows how to handle them in the ControlHandler function.
The STOP request is sent when the SCM stops the service. For example, if the user manually stops the service from the Services applet, the SHUTDOWN request is issued to all running services by the SCM, when the machine shuts down. Both cases are handled identically:
- Writing to the log file Monitoring is stopped.
- The SERVICE_STOPPED state is reported to the SCM.
Since the ServiceStatus structure is global to the whole program, the worker loop in ServiceMain stops after the current state changes and the service thread terminates. There are other control requests, such as PAUSE and CONTINUE, that are not handled in this example.
The control handler function must report the service status, even if that status remains the same, every time the SCM sends a control request. Hence, SetServiceStatus is called in response to all requests.
|Figure 1: The Services applet displaying the MemoryStatus service.
Step 4: Installing and Configuring a Service
The program is ready and may be compiled into an exe file. I created MemoryStatus.exe and copied it into C:\MyServices folder on my computer. To install this service on your operating system, you'll need to use the SC.EXE executable, which comes with the Win32 Platform SDK tools. You will use this utility to install and remove the service. The other control operations will be done through the Services applet.
Here is the command-line to install your MemoryStatus service:
sc create MemoryStatus binpath= c:\MyServices\MemoryStatus.exe
Issue the create command. This specifies the service name and path to the binary file (notice the space between binpath= and the path). You can now use the Services applet to control the service (see Figure 1
Start and stop the service using the toolbar of the applet.
|Figure 2: The Properties window for the MemoryStatus service
The startup type of MemoryStatus is manual, which means that it will start only on-demand. Right-click on the service and choose Properties from the context menu, to get the properties window for the service (Figure 2). This is where you can alter the startup type along with other settings. You can also start/stop the service from the General tab.
To remove the service from the system, execute the following command:
sc delete MemoryStatus
Specify the delete option and the service name. The service will be marked for deletion and will be completely removed after the next restart.