\[Editor's Note: VB Solutions is about using Visual Basic (VB) to build a variety of solutions to specific business problems. This column doesn't teach you how to write VB, but how to use VB as a tool to provide quick, easy-to-implement solutions that you can use right away.\]
In this month's VB Solutions column, I'll show how you can use Visual Basic (VB) to build the Automated Mass Ping utility. You can use this utility to monitor your network systems and quickly identify available systems and systems you cannot contact. You can define a list of networked system names or IP addresses to Automated Mass Ping and specify a time interval for testing availability. Automated Mass Ping periodically wakes up and pings each of the networked systems and reports the results. Screen 1, page 200, presents the Ping Status tab of the Automated Mass Ping window, which appears when you execute the utility.
Using Automated Mass Ping is very easy. You simply click Start Ping on the Ping Status tab to start the timed ping process for the list of systems. To stop the automated ping process, you click Stop Ping. However, before you begin using Automated Mass Ping, you need to define the list of systems that you want to monitor and specify the ping interval on the Settings tab, as shown in Screen 2, page 200.
You can enter either TCP/IP host names or TCP/IP addresses in the text box at the top of the Settings tab, and then click Add to add the new entry to the list of systems to be pinged. If you want to ping a TCP/IP host by name, you must have an entry for that host in your system's HOSTS file, or you must be attached to a Domain Name System (DNS) server that has an entry for the target host name. If the systems that you are pinging connect across the Internet, you can use your Internet Service Provider's (ISP's) DNS server to resolve host names. To remove an entry from the list, you must select the entry and then click Remove. If you want to clear the entire list, you click Clear.
The Ping interval setting controls how often (in seconds) Automated Mass Ping will begin pinging the list of systems. In Screen 2, you can see that the Ping interval is set to 300 seconds, which means that Automated Mass Ping will begin pinging the list of systems at 5-minute intervals.
The Beep on Ping check box controls whether Automated Mass Ping will beep if an error occurs during the ping process. Selecting the check box turns on the beep; clearing the check box lets Automated Mass Ping function silently.
You can save the values on the Settings tab to the Registry by clicking Save Settings. If you save the settings, they will be automatically loaded the next time Automated Mass Ping starts. Otherwise, the settings persist only until the application ends.
Inside Automated Mass Ping
Now that you've seen how to use Automated Mass Ping, let's take a closer look at how to build this utility. At the heart of Automated Mass Ping is ping32.dll, a DLL that I built based on the ping.c sample Microsoft distributes as a part of its Winsock development sample. The original Win32 command-line version of ping.c operates from only a text-oriented command line. The original ping.c does not operate under program control, and it cannot return the ping information to another application. I converted this sample command-line utility to a DLL that any development environment that supports external DLLs (such as VB) can call. Converting the Microsoft example to a DLL lets you call the ping function from VB and return the results of the ping to the calling applications. (You can download ping32.dll and its source code with the code for Automated Mass Ping from the Windows NT Magazine Web site at http://www.winntmag.com.)
Before you can use the functions that an external DLL contains, you must declare the functions using a .bas or .cls module. Ping32.dll contains one function (ping), which is declared in the ping.bas file. The VB declaration for the ping function follows:
Declare Function ping _Lib "ping32.dll" _(ByValsHostName$, _ByVal sIPAddr$, _ByVal iDataLen%, _lPingTime&, _ByVal iTimeout%, _ByVal iVerbose%) As Integer
The first parameter of the ping function is a string that contains either the name or the IP address of the system to be pinged. The second parameter is a string that the ping function returns. This string contains the IP address of the pinged system and lets the calling program retrieve the IP address for a given TCP/IP host name. The third parameter specifies the size of the data packet sent with the ping. The maximum data length that ping32.dll allows is 1024 bytes. The fourth parameter, a long variable, returns the elapsed milliseconds the ping function required to execute. The fifth parameter contains the maximum time in milliseconds that the ping function will wait for a response for sent or received packets. The sixth parameter specifies the mode of operation for the ping function. If you set this parameter to True, ping32.dll will run in verbose mode, the mode that displays all ping results and errors in a message box. Setting the sixth parameter to False runs ping32.dll in silent mode, the mode that reports any ping results and errors in the ping function's return code and output parameters.
Next, let's look at how to incorporate the ping function into the application. At the core of Automated Mass Ping is the Ping_List subroutine presented in Listing 1.
The Ping_List subroutine is the workhorse of the utility. Ping_List displays the progress of the ping process and the status of each ping, and calls the ping function. The first few lines of code in Listing 1 declare Ping_List's working variables. At callout A in Listing 1, the subroutine clears the List_PingStatus list of any old status entries. The subroutine then retrieves the number of items in the List_IP name list using the ListCount method; at B in Listing 1, you can see the code that loops through the items in the list. As soon as the subroutine reads an entry from the list, it adds the entry to the List_PingStatus list; the subroutine uses the List_PingStatus.ListIndex method to make the newly added item the current selection. The ListIndex method lets the list scroll as the subroutine adds each item, which keeps the current ping status in view.
At C in Listing 1, you can see that the subroutine calls the ping function within the loop. Before calling the ping function, the subroutine uses VB's Space function to make sure that the sIP string variable is adequately sized to contain the returned IP address. The returned IP address has the form 999.999.999.999, and it can contain a maximum of 16 bytes (15 bytes plus the null character). Like any string variable that an external DLL returns, the return variable must be the right size. If it is too small, the application generates a memory violation error.
Next, the ping function performs the task of pinging the remote system. The first parameter of the ping function is the List_IP.List(i) variable, which contains the text from the current list entry. The second parameter, sIP, will contain the returned IP address. The third parameter specifies the size of the data buffer that will be sent to (and returned by) the remote system. This example uses a data buffer size of 64, which means that the utility will ping 64 bytes between the local and remote systems. The fourth parameter, lPingTime, will contain the time in milliseconds that it took ping32.dll to complete the ping function. The fifth parameter sets the ping timeout value to 2000 milliseconds (2 seconds). Finally, the code sets the sixth parameter to 0, which specifies that the ping function will run in silent mode and will not display any message boxes.
After the ping function completes, the subroutine adds the values from the returned variables (sIP and lPingTime) to the list. Because the sIP variable returns as a C-style null terminated string, the code at D in Listing 1 strips the non-displayable null character, Chr$(0), from the string before adding the string to the List_PingStatus list. If the ping function fails, the subroutine checks the Beep setting and optionally beeps the user. The program displays a failed message and shows the return code as an entry in the ping status list. After updating the list, List_PingStatus.ListIndex positions the list entry to ensure that the current ping status entry is always visible.
Timing Is Everything
Now that we've analyzed the Ping_List subroutine, which pings the remote TCP/IP hosts, you might want to know how Automated Mass Ping executes that code at regular intervals. VB's built-in timer function makes this functionality extremely easy to implement. When the user clicks Start Ping on the Ping Status tab, the utility executes the Command_StartPing_Click subroutine, shown in Listing 2.
As you can see in Listing 2, the first thing Command_StartPing_Click does is call the Ping_List subroutine, which immediately initiates the first ping process. Next, Command_StartPing_Click sets the Timer1.Interval property to the interval value from the Settings tab, and sets the Timer1.Enabled property to True to activate the timer. The timer will fire at the interval specified in the Timer1.Interval property. Finally, the subroutine disables the Start Ping button, which prevents the user from starting another timer process, and enables the Stop Ping button.
When the timer interval has elapsed, the timer control then fires the
Timer subroutine, which you see in Listing 3, page 202. The timed execution of Timer1_Timer runs the ping process at regular intervals. This subroutine is simple: All it does is call the Ping_List subroutine.
Saving and Retrieving Settings
The final important part of the Automated Mass Ping utility handles saving and retrieving configuration settings. The utility saves the settings when the user clicks Save Settings on the Settings tab; clicking Save Settings executes the Command_Save_Click subroutine, which you see in Listing 4.
Automated Mass Ping uses VB's built-in SaveSetting function three times to write the setting values to the Registry. The SaveSetting function makes the Registry emulate an INI file. The SaveSetting function is easy to use, but it saves the settings in only the HKEY_CURRENT_USER\Software\VB and VBA Program Settings key.
The first, second, and third parameters of the SaveSetting function uniquely identify the Registry entry, and the fourth parameter contains the value to be saved. The first parameter specifies the application's name; for Automated Mass Ping, I used the string "Automated Ping". The next parameter specifies the section or subkey of the Registry that will be used. For this parameter, I specified "Startup" to denote that the values will be used when the application starts. The third parameter specifies a unique setting for the application. Each SaveSetting statement in Listing 4 uses a different key name for the third parameter: "Interval", "Beep", and "List". As you might guess, the Interval key stores the timer interval from the Settings tab. The Beep key stores the value from the Beep on Ping check box, and the List key stores the list of systems entered on the Settings tab. The List2String function extracts the entries from the list of systems (List_IP) and places them in the sList string. A comma separates each TCP/IP host entry in the sList string.
When the Automated Mass Ping utility first starts, the Form_Load subroutine (shown in Listing 5) retrieves any previously saved Registry settings. As you can see in Listing 5, the Form_Load subroutine uses VB's GetSetting function to retrieve the values from the Registry. GetSetting works very much like SaveSetting. The first three parameters of the GetSetting function identify the key to be retrieved; the optional fourth parameter supplies a default value that's used if the key cannot be retrieved. The GetSetting function returns the retrieved Registry value to the variable that's on the left side of the assignment operator (=). The String2List function in Listing 5 extracts each TCP/IP host name from the comma-delimited string containing the list of systems to be pinged, and adds the host name to the List_IP list.
Putting the Utility to Work
You can use the Automated Mass Ping utility to provide a continuously updated report on the availability of a list of TCP/IP-attached systems. These systems can connect across the Internet, or they can connect across your private LAN or WAN network. Although Automated Mass Ping simply displays the status of the last ping attempt, you can easily modify this utility to perform other actions, such as sending a network message to notify you when an important system goes down or recording the ping results in a database file to track the availability of your systems. In next month's VB Solutions column, I'll explore how to build a graphical HOSTS file editing utility that puts Automated Mass Ping to work.
We Want Your VB Code!
Windows NT Magazine wants to publish your VB solutions. Send us any interesting and useful VB solutions you've created for your business's problems. If we agree that your VB solutions are valuable to our readers, we'll publish your code and pay you $100. You can send contributions or ideas for VB solutions to me at firstname.lastname@example.org.