November 27, 2014
Hot Topics:

Writing a Windows Service in Managed C++

  • December 29, 2003
  • By Kate Gregory
  • Send Email »
  • More Articles »

Uninstalling the Service

If you installed your service right from the Debug directory, you don't need to uninstall it while you're making changes to it. Just stop it, rebuild, and start it again. But, if you want to uninstall it, just go back to the Visual Studio Command prompt, navigate to the Debug directory, and use this command:

CGNotifier.exe -Install /u

The service will disappear from the lists of services in both Server Explorer and Computer Management. However, you may have to refresh the lists to see that it's happened.

Waking to Do Some Work

Of course, the service I've shown you so far doesn't do anything. To turn it into one of those "wake up at a set time" services, a good first step is to add a configuration file to the project. Mine looks like this:

<configuration>
  <appSettings>
    <add key="runhour" value="22" />
  </appSettings>
</configuration>

As I showed in my previous column, you need to add a post-build step to the project that copies the app.config file into the target directory (Debug or Release) using the application name. The command line to enter for the post-build step is:

copy app.config $(ConfigurationName)\$(TargetFileName).config

To read the setting, you can add code to OnStart or to mainLoop(), just before the loop. I prefer to keep OnStart() as empty as possible, so I added these lines to mainLoop():

String* sHour = 
  Configuration::ConfigurationSettings::
                 AppSettings->get_Item("runhour"); 
int runHour = System::Int32::Parse(sHour);
bool rantoday = false;

The loop then looks like this:

stopping = false;
while (!stopping)
{
   if (DateTime::Now.Hour == runHour && !rantoday)
   {
      // do the task
      rantoday = true;
   }
   else
      rantoday = false;
   Threading::Thread::Sleep(loopsleep);
}

You want this code to run only once each day, after we've ticked over to the appointed hour, so the rantoday flag flips to true after the service does whatever it's supposed to do. It flips back to false once we're in a different hour.

That just leaves the little matter of doing something at the appointed hour. You might root through a database for new records and send subscribers notification that something (a product? a real estate listing? a job posting?) has been added to your system. You might root through a database for old records, or the file system for old files, and delete them. There are more things a service might do than I can list. Whatever the task, you need to tell someone you did it. Because a service doesn't have a user interface, you can't just pop up a message box. One elegant way to leave a little trail of breadcrumbs is to use the event log.

These lines before the loop in mainLoop() set up the log:

Diagnostics::EventLog* log ;
if (! Diagnostics::EventLog::SourceExists("CGNotifierService") )
    Diagnostics::EventLog::CreateEventSource("CGNotifierService",
                                              CGNotifierLog");
log = new Diagnostics::EventLog("CGNotifierLog");
log->Source = "CGNotifierService";

While you don't have to set both the log and the source (and most examples don't), I like to because then my messages get their own node under Event Logs in Solution Explorer.

To write to the log, you need only one line of code—I put this in the place of the "do the task" comment:

log->WriteEntry("It's run time for the service. Insert work here.",
                Diagnostics::EventLogEntryType::Information);

There you have it: a service that can be installed and uninstalled, stopped and started, and once a day writes a message into the event log. From here, there's no stopping you. Windows services in C++ can do anything that other .NET applications can do, and as long as you stay away from the VB and C# examples, you won't get confused by the slightly different spin we C++ types get on service project creation.

About the Author

Kate Gregory is a founding partner of Gregory Consulting Limited (www.gregcons.com). In January 2002, she was appointed MSDN Regional Director for Toronto, Canada. Her experience with C++ stretches back to before Visual C++ existed. She is a well-known speaker and lecturer at colleges and Microsoft events on subjects such as .NET, Visual Studio, XML, UML, C++, Java, and the Internet. Kate and her colleagues at Gregory Consulting specialize in combining software develoment with Web site development to create active sites. They build quality custom and off-the-shelf software components for Web pages and other applications. Kate is the author of numerous books for Que and Sams, including Microsoft Visual C++ .NET 2003 Kick Start.

# # #





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel