March 2, 2021
Hot Topics:

Program and Employ Windows Services for Microsoft SharePoint 2007

  • By Gustavo Velez
  • Send Email »
  • More Articles »

The template creates two override routines, for "OnStart" and "OnStop", but other overrides may be created manually ("OnPause", "OnContinue", "OnShutdown", "OnSessionChange", and so on). Also, if it is necessary for the program's logic, a "Main" method can be added to the class.

The Windows Service sample must run every 24 hours, so it is necessary to program a timer. The System.Threading NameSpace contains the classes to create a timer and after a reference and directive for the NameSpace is configured, the following lines of code in the "OnStart" method create a timer for 86,400,000 milliseconds (24 hours):

int TimeInterval = 86400000;
TimerCallback TimerDelegate =
   new TimerCallback(CreateOutputSharePoint);
Timer ServiceTimer =
   new Timer(TimerDelegate, null, 500, TimeInterval);

Be aware that the integer used for the time interval has a maximum value of 655,465,540 milliseconds, or approximately 7 days. The "TimerDelegate" variable will run the "CreateOutputSharePoint" routine each time the "ServiceTimer" elapses; the "ServiceTimer" timer object starts after 500 milliseconds (time to stabilize the service after initialization), and fires the "TimerDelegate" after the "TimeInterval" has elapsed. The third parameter of the Timer can be an integer, as in this case, but if it is necessary to have more time between the events, a "Long" or "TimeSpan" can be applied.

The private method "CreateOutputSharePoint" loops across the Sites in the Portal and registers the Webs of each Site and collects the documents and elements of the Library and List in each Site. The information is written to a text file:

string myData = string.Empty;
TextWriter myWriter =
   new StreamWriter(@"c:\\SharePointSummary.txt");

SPSite mySite = new SPSite("http://ServerName");

foreach (SPWeb myWeb in mySite.AllWebs)
   myData += " - Web: " + myWeb.Title + "\r\n";

   foreach (SPList myList in myWeb.Lists)
      if (myList.Hidden == false && myList.OnQuickLaunch == true)
         myData += "    - List: " + myList.Title + "\r\n";

         foreach (SPListItem myItem in myList.Items)
            myData += "        - Item: " + myItem.Name + "\r\n";


In the code, the "TextWriter" and "StreamWriter" objects are constructed to save the found information. A "SPSite" reference is made for the Portal site collection and the first loop goes through the Webs (of the "SPWeb" type) in the site. The inside loop scans the Lists collection, searching for Lists and Libraries that are not hidden (SharePoint uses many hidden Lists to save internal working data) and enumerates the elements and documents found.

The timer interval and the URL to create the instance of the SPSite object are hard coded in the example, but if they need to be configured, it is possible to save them in the Windows Registry regardless of the method of configuration. Windows Service code can utilize all the DotNet techniques available for the developer, including write/read to/from the Registry or physical files, such as configuration archives.

A note of caution is necessary regarding the exception handling. Be conscientious with handling each possible exception because the Service will not sound an alert if there is a problem; instead, the thread will be cleared by the Windows Garbage Collector and the service will continue operating and generating exceptions. The try/catch statement in the example will trap each error and write it to the Event Log:

   . . .
catch (Exception ex)
   EventLog.WriteEntry("Error in Windows Service", ex.ToString(),

In the same way, initialization and finalization are logged to the EventLog from the "OnStart" and "OnStop" methods.

The SharePoint functional source code is ready, but Windows Services needs an installer to alert the Service Control Manager that the service exists and to register the components inside Windows. Visual Studio has components to accomplish this: Return to the Design view of the Visual Studio project, right-click anywhere inside the background of the designer screen, and select "Add Installer"; this action will generate a new class ("ProjectInstaller", named by default) and add two components ("serviceProcessInstaller1" and "serviceInstaller1") to the project.

Select the "serviceProcessInstaller1" properties and change the Property "Account" to "LocalSystem". Select the "serviceInstaller1" and make the following changes:

Property "StartType"   = "Automatic"
Property "Description" = "Example of Windows Service"
Property "ServiceName" = "ScanWss Windows Service"
Property "DisplayName" = "ScanWss Windows Service"

If necessary, the names of the components can be changed. Finally, build the solution and rectify any errors found by the compiler.

Install and Use Windows Services

After compilation, the service can be installed using the "InstallUtil.exe" tool because, unlike most Visual Studio projects, the application does not run directly from the IDE or double-clicking at the executable. The utility can be found in the directory "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\" or can be used directly from the Visual Studio 2005 Command Prompt with the syntax:

installUtil [path to the service compiled exe file]

Page 2 of 3

This article was originally published on August 22, 2008

Enterprise Development Update

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

Thanks for your registration, follow us on our social networks to keep up-to-date