Building a Remote Services Monitor

This VB application lets you monitor remote servers' services from your desktop.

Bob Hyland

August 31, 1998

12 Min Read
ITPro Today logo


Make sure your network's vital services are functioning properly

Developers build 32-bit applications for Windows NT networks on an infrastructure of NT services. Each service provides functionality at a system level or at a level that is available to other computers on the network. Examples of services that NT Server runs include the Computer Browser, Windows Internet Naming Service (WINS), remote procedure call (RPC), FTP, and SQL Server services.

Applications from Microsoft and third-party vendors rely on NT services to function properly. When an NT service stops running, its failure affects all the applications and users that depend on the service, reducing the users' capacity to work. Therefore, the sooner a developer or administrator learns about a service's failure, the better off everyone is.

You can interactively view and manage your local system's services using the Control Panel Services applet, but the applet doesn't let you view remote systems' services. Server Manager (which comes with NT Server and is available in all versions of Microsoft Windows NT Server Resource Kit) solves the remote management problem, but neither program produces warnings when a service fails.

To receive warnings when services on remote systems fail, you need the Services Monitor program that I build in this article. Services Monitor lists the domains and computers within your LAN or WAN, lets you choose services you want to monitor on any NT servers on the network, and alerts you when selected services fail.

Using Services Monitor
When you start Services Monitor, the program builds a tree-view display that contains an expandable icon for each domain and server in your network, as Screen 1, page 188, shows. If your network is large or widely distributed across a WAN, the tree-building process can take 30 minutes or more, depending on your network speed and the size of your WAN. If you expand the icon for a domain, Services Monitor builds a list of services for each server in that domain. You can alter Services Monitor to build the list of services at the same time youbuild the lists of domains and servers, but querying every server about its services increases your startup time considerably--an unnecessary inconvenience if you want to monitor services on only a few systems on the network.

Services Monitor uses Visual Basic's (VB's) Tree View control to list the domains, systems, and services on your network. You expand a domain icon to view the systems in the domain and expand a system icon to view the services that the system runs. Services Monitor displays a check box next to services that are running. You double-click a service's check box to instruct Services Monitor to monitor that service. NT services that aren't running are not available formonitoring. Services Monitor displays a red No Service circular icon next to each stopped service.

Services Monitor periodically polls the status of the services you select for monitoring. You use the Polling Interval text box to set the polling interval; polling intervals can range from 10 seconds to 60 seconds.

Services Monitor also lets you select the action that you want NT to perform when a monitored service stops. Services Monitor lets you set the program to produce a beep or play a .wav file on the machine where Services Monitor is running.

After you select monitoring options, click Start Polling to start ServicesMonitor. The program places an icon in the right corner of your taskbar andbegins periodically polling services. You can right-click the Services Monitoricon to view the status of monitored services. The Show Service Statuses window,which Screen 2 shows, will appear. The window displays a stoplight icon next toeach monitored service. When a service is active, its stoplight icon shows agreen light; when a service stops, its stoplight icon shows a red light.

Inside Services Monitor
Services Monitor's core functionality rests on two types of Win32 APIs. The program uses the Windows Networking (WNet) APIs in mpr.dll to list the networked domains and servers. Then it uses the Windows Service Control Manager (SCM) APIs from advapi32.dll to poll the status of services running on local and remote NT systems. To make these APIs easy to reuse in other applications, I encapsulatedthem in VB classes. (For more information about the networking and service classes that Services Monitor uses, see the sidebar "Classes for Networking and Services.")

Retrieving Domain and Server Names
When Services Monitor starts, it uses the WNetOpenEnum API to open a networkenumeration, then uses the WNetEnumResource API to traverse the enumeration.Services Monitor uses the com-bination of the WNetOpenEnum and WNetEnumResourcefunctions to reveal a domain's hierarchy of resources.

When you start Services Monitor, the WNetOpenEnum function opens thenetwork provider level, and the WNetEnumResource function lists the network'sproviders, such as Microsoft Windows Network, Novell NetWare, or Banyan Vines.At the next level, Services Monitor uses the WNetOpenEnum and WNetEnumResourcefunctions to reveal the domains in the Microsoft Windows Network. Theenumeration level beneath the domains lists each of the domains' networkedcomputers that is running a server service and sharing resources on the network.This list of each domain's servers can include machines running NT Workstation,NT Server, Windows for Workgroups (WFW), Windows 95, and LAN Manager servers,but Services Monitor can monitor services only on the NT systems.

Listing 1, page 190, shows sample code that uses the WNetOpenEnum andWNetEnumResource functions. At callout A, Listing 1 contains the WNetOpenEnumfunction, which takes five parameters. The first parameter sets the scopeof the enumeration. The value RESOURCE_GLOBALNET tells the WNetEnumResourcefunction to display all the resources on the network. The second parameterspecifies the type of network resources the WNetEnumResource function needs tolist. The value RESOURCETYPE_ANY tells the function to include disk and printingresources. The third parameter further specifies the type of resource theWNetEnumResource function needs to return. The value 0 tells the function toreturn local and networked resources. The fourth parameter is the most critical.It is a structure that sets the level of the enumeration (i.e., networkprovider, domain, or server). The NETRESOURCE structure Services Monitor uses inparameter four is

Type NETRESOURCE

dwScopedwTypedwDisplayTypedwUsagelpLocalNamelpRemoteNamelpCommentlpProvider

As LongAs LongAs LongAs LongAs StringAs StringAs StringAs String

You place the string Microsoft Windows Network in the lpProvider member ofthe NETRESOURCE structure to start Services Monitor's enumeration process. TheWNetEnumResource function fills in the other structure values after it startsenumeration. The dwScope, dwType, and dwUsage members of the NETRESOURCEstructure define the same information as the first three WNetOpenEnumparameters. The dwDisplayType member provides additional information about aresource's type; it reports whether network resources are domains, servers, orshares. The lpLocalName member contains the names of any remapped local devices.The lpRemoteName member contains the name of the network resource, and lpCommentcontains a description of the resource. The WNetOpenEnum function uses its fifthparameter to return an enumeration handle that the WNetEnumResource functionuses in subsequent calls.

At B, Listing 1 calls the WNetEnumResource function to enumerate thenetwork resources. The WNetEnumResource function takes four parameters.The first parameter is the handle that the WNetOpenEnum function returns. Thesecond parameter identifies the number of entries the WNetEnumResource functionneeds to return per call. The third parameter is a buffer that contains theNETRESOURCE structure that the WNetEnumResource function returns. The fourthparameter specifies the size of the third parameter's buffer.

The NETRESOURCE structure that the WNetEnumResource function returns is apointer. Listing 1's CopyMemory function copies the NETRESOURCE information fromthe buffer pointer into a structure so that Services Monitor can use theinformation in VB.

At C, Listing 1 uses the dwDisplayType member of the NETRESOURCE structureto determine whether the resource is a domain, server, or shared disk orprinter. A VB Select statement then adds the structure information to thecollection for that type of resource. If the NETRESOURCE structure containsdomain information, the Select statement uses the structure information tocreate a new CDomain object, then passes the structure information as aparameter to the CDomain object's Init function. If the NETRESOURCE structurecontains server information, the Select statement creates a CServer object andpasses the structure information to the CServer class Init function. ServicesMonitor uses the CDomain and CServer objects to display resource information inthe tree view. At D, Listing 1 uses the WNetCloseEnum function to close theenumeration.

The same NETRESOURCE structures that Services Monitor uses to representdomains can enumerate servers, the children of domains. After theWNetEnumResource function enumerates a resource, the third parameter in thecalling list passes a pointer that identifies the NETRESOURCE structure to theWNetOpenEnum function. The pointer tells the WNetOpenEnum function to move tothe next level of the hierarchy and open an enumeration for the resource'schildren. Services Monitor uses the same functions and structures to enumerateevery level of the network resource hierarchy, so the WNetOpenEnum andWNetEnumResource routines must be common code that works for all the hierarchy'slevels.

Listing Services
The NT SCM subsystem starts automatically when a system boots. The SCM readsinformation from a database in the HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices Registry key about two types of services: installedservices, such as the SQL Server or Workstation services, and driverservices, such as 4mmDAT and Atdisk (kernel and file system drivers). ThisRegistry key contains information about each service's security context, whereits executable is, whether it starts automatically or manually, whether itsfailure is critical to the system, and the names of other services it dependson. Services Monitor monitors only installed services, but you can alter thecode to also monitor driver services.

When a user expands a domain, Services Monitor retrieves a list ofinstalled services from every server in the domain. Listing 2 shows the codethat obtains the list of installed services for each remote server.

At A, Listing 2 uses the OpenSCManager API call to list a machine'sservices. The OpenSCManager function takes three parameters. The first parametercontains the server name that the WNetEnumResource function returns in Listing 1. The second parameter is a string that identifies the services database for Services Monitor to open. The value "ServicesActive" tells the OpenSCManager function to open the database of active services. The third parameter specifies the type of permissions Services Monitor needs to access the target machine's SCM database; the value SC_MANAGER_ENUMERATE_SERVICEdefines the access rights that Services Monitor needs. When the OpenSCManager function completes, it returns a handle that the EnumServicesStatus function uses to create a buffer of ENUM_SERVICE_STATUS structures.

At B, Listing 2 shows the EnumServicesStatus function, which takes eightparameters. The first parameter is the handle the OpenSCManager functionreturns. The second parameter is a constant that specifies the type of servicesthe EnumServicesStatus function needs to poll. The value SERVICE_WIN32 tells thefunction to list installed services rather than driver services. The thirdparameter further specifies the type of services the function returns. The valueSERVICE_STATE_ALL tells EnumServicesStatus to list both active andinactive services.

The fourth parameter is the buffer in which EnumServicesStatus places anarray of the ENUM_SERVICE_STATUS structures the function returns. TheENUM_SERVICE_STATUS structure is

Type ENUM_SERVICE_STATUS

lpServiceNamelpDisplayNameServiceStatus

As LongAs LongAs SERVICE_STATUS

The ENUM_SERVICE_STATUS structure's members identify the service's name, the name Services Monitor will display for the service, and a nested structure called SERVICE_STATUS that contains information about the service's current status.

The fifth EnumServicesStatus parameter defines the size in bytes of thefourth parameter's buffer. The sixth parameter returns the number of bytes the buffer needs to hold the array of ENUM_SERVICE_STATUS structures. Services Monitor allocates a buffer size of 16KB, which is larger than necessary in most cases. The seventh parameter contains the number of services the EnumServicesStatus function returns. The eighth parameter tells Services Monitor how far down the target SCM database's list of services to start enumerating services. This value needs to be 0.

When the EnumServicesStatus function call completes, it returns a new valuein the eighth parameter. If the function places a 0 in the eighth parameter, thebuffer is large enough to enumerate all the target machine's services. If thefunction returns a non-zero value in the eighth parameter, the call failed, andyou need to check the value of the VB Err object's LastDLLError property. Ifyour computer's last DLL error is ERROR_MORE_DATA, the EnumServicesStatus bufferis too small, and the eighth parameter's value identifies the entry in the SCMdatabase's services list where Services Monitor needs to resume enumeration whenthe buffer has space for the remaining data. When Services Monitor encountersthe ERROR_MORE_DATA error, it increases the size of the buffer and triesthe EnumServicesStatus call again. Services Monitor continues to try theEnumServicesStatus function call until the buffer is large enough and the callcompletes successfully or the call returns an error other than ERROR_MORE_DATA.Any other LastDLLError entry indicates that a more serious error preventsServices Monitor from enumerating services; if it encounters an error other thanERROR_MORE_DATA, Services Monitor exits.

At C, Listing 2 processes the array of ENUM_SERVICE_STATUS structures thatthe EnumServicesStatus function returns and creates a CService object for eachservice the EnumServicesStatus function adds to the colServicescollection. As Services Monitor processes the arrays, it uses the Tree Viewcontrol to display each server's list of services and each service's status. AtD, Listing 2 uses the CloseServiceHandle function to close the handle to the SCMdatabase.

Updating Services' Status
When the Services Monitor's polling timer expires, the application queriesthe status of each selected service using the QueryServiceStatus API. Listing 3, page 193, shows the code that queries services' status.

At A, Listing 3 uses the OpenSCManager function to connect to the SCMdatabase. The value SC_MANAGER_CONNECT in OpenSCManager's third parametertells the function to open a connection.

At B, the OpenService function uses the handle that the OpenSCManagerfunction returns to acquire a handle to a service. The OpenService functiontakes three parameters. The first parameter is the handle to the SCM databasethat the OpenSCManager function returns. The second parameter is the service'sshort name. The third parameter is a constant that specifies the permissionlevel the SCM operation needs. The value SERVICE_QUERY_STATUS gives theOpenService function permission to return the service's status.

At C, Listing 3 uses the QueryServiceStatus function to retrieve theservice's current status. The QueryServiceStatus function takes two parameters.The first parameter is the service handle that the OpenService function returns,and the second parameter is a structure that contains the service's currentstatus. At D, Listing 3 uses the CloseServiceHandle function to close thehandles to the SCM database and the service.

Services Monitor's Functionality
This article uses the WNet and SCM APIs to build a Services Monitorapplication. You can immediately put this utility to work on your network orcustomize the code to fit your needs. Services Monitor provides a display andalarm when a service fails, but you can modify the code to perform otheractions, such as send email or attempt to restart the failed service.

NT 5.0 will include another method for querying the status of services onnetworked systems: Active Directory Services. Nevertheless, Services Monitoroffers service monitoring functionality, and the WNet and SCM APIs will continueto support NT users for the foreseeable future.

Sign up for the ITPro Today newsletter
Stay on top of the IT universe with commentary, news analysis, how-to's, and tips delivered to your inbox daily.

You May Also Like