- Defining the Windows Service Project
- Adding Some Simple Test Code
- Registering the Service
- Creating the Test Program
- Bottom Line
Adding Some Simple Test Code
At this point, your Windows service is configured, but it won't do anything. The code will even compile and you could install it. The Windows service comes with several predefined methods, but the two most important are OnStart() and OnStop() because they define how the Windows service reacts to standard commands from the Services console. You'll also need to define some custom methods to perform the work you intend for the Windows service to do. In this case, the Windows service will simply keep track of the number of times it has been accessed. Listing 1 shows some code to perform this task.
Listing 1 Defining What the Windows Service Will Do
private: // A variable that tells how many times the Windows // service is accessed. Int32 _NumberOfAccesses; protected: void OnStart(String* args[]) { // Set the number of accesses to 0. _NumberOfAccesses = 0; } void OnCustomCommand(Int32 Command) { // Execute the default command. Microsoft reserves command // numbers 0 through 127 for default service behaviors. if (Command < 128) ServiceBase::OnCustomCommand(Command); // Increment the number of accesses. The client application // calls this command number to increment the access count. if (Command == 128) DoAccess(); // Make an event log entry. Because the Windows service can't // provide a user interface, it uses the event log for communication. if (Command == 129) GetAccess(); } public: void DoAccess() { // Increment the number of accesses. _NumberOfAccesses++; } void GetAccess() { StringBuilder *Output; // The output data. // Create the output data. Output = new StringBuilder(); Output->Append("The number of user accesses is: "); Output->Append(_NumberOfAccesses); // Write an entry in the event log. this->get_EventLog()->WriteEntry( "TrackAccess", Output->ToString(), EventLogEntryType::Information, 1200, 99); }
NOTE
I use a StringBuilder because it's automatically garbage-collected and ensures that there are no memory leaks in the Windows service. In addition, this is a managed application, so the StringBuilder is the most appropriate method of building the string.
The _NumberOfAccesses variable simply holds the number of times a test application has accessed the service since you started the service. Whenever the service is restarted, Windows calls OnStart(), which resets _NumberOfAccesses to 0. In this case, there isn't any need for an OnStop() process because OnStart() takes care of the required processing.
The OnCustomCommand() method is the cornerstone of the Windows service. An application can't access the Windows service directlyit must go through Windows to perform the task, using a task number. Windows reserves tasks 0 through 127 for its own use, so the first open task number is 128. The code automatically passes all of the default commands to the base class. When the code sees a 128 command, it updates the access count by calling DoAccess(). Likewise, when the code sees a value of 129, it calls GetAccess to create an event log entry that contains the number of accesses.
The two public methods, DoAccess() and GetAccess(), are relatively simple. Calling DoAccess() merely increments _NumberOfAccesses. Calling GetAccess() creates a StringBuilder containing a message that the code places in the event log by using the EventLog::WriteEntry() method.