Diderick Oerlemans
Wouldn't it be nice to be able to create an agent that's running on your NT Server as an NT service? Well, it's not so hard to do, because it's possible to use VB!Chris Duke, who runs an excellent site for advanced VB developers at vb.duke.net, got me started on this agent project when he posted some articles about creating an NT service using VB. One thing you need is NTSVC.OCX, an unsupported OCX that Microsoft has been distributing (as source code) on MSDN for some time now.
What I needed to build was an agent that could read e-mail, parse it, and perform some actions on a SQL Server. Once I'd done just that, I published my experiences on vb.duke.net, but because I received so many requests for source code, I thought it would be a good idea to send this document to Visual Basic Developer so more people can benefit from my findings.
PreparationsYou'll need to prepare some things before doing the coding. Start by getting the newest active messaging library -- you'll need version 1.1 at a minimum. Next, make sure you install Outlook 8.01 (this is also the minimum version that will work) on the target server (nope, Exchange 5.0 client with the service pack doesn't work!). Also, you'll need to run regsrv32 to register the NTSVC.OCX on both your development PC and the target server.
Then, set up a domain user with a mailbox on Exchange server. The domain user should have enough rights on the target server so it can use the Outlook client. Next, log onto the target server and create the default Exchange profile. After creating your agent and installing it as a service, you should set the service to log onto NT using the domain user you just created.
Using the service OCXCreate a main form and drop the NTSVC.OCX on it. Fill in the name and display name properties. Initialization of the service should take place in the load event of the main form:
|
As you can see, we start by parsing the command line option, to determine whether the service should be (un)installed. In other cases -- for example, when the service is started by the NT service control manager -- it will start the service with the NTService.StartService method.
The OCX also exposes a very handy function to log events to the NT application log. I wrote a little wrapper sub to use this function:
|
Because you usually don't have a console for your service (except when (un)installing), you should log all errors and other useful stuff. For example, you could have the form load error handler log any errors using the ServiceLog subroutine. The service OCX will raise the following event when starting:
|
What I've done here is initialize the SQL Server connection and start a mail session (more about this later). The SQL Server connection should pose no difficulties. In my case, I used DB-Library and integrated security, but ADO or RDO should also work. I also initialized a timer control (for polling the mailbox) on the main form. If you set the Success Boolean to false, the OCX will notify the NT service control manager that the service couldn't be started -- Success to true does the opposite. Note that all relevant information is again logged to the application log using the ServiceLog wrapper sub.
When the service is stopped (using the NT service control manager, for example), the following event procedure is fired:
|
It does the obvious -- disconnects from SQL Server, closes the mail session, unloads the form, and thus ends the service. Using active messaging
This is where most people who mailed me got stuck. I again stress the fact that you need the newest versions of active messaging (or CDO, for Collaboration Data Objects, as it's called these days) and Outlook installed. Active messaging version 1.0 will not work, and Outlook 8.0 will not work.
I created a generic class to hold my active messaging session (this isn't required, of course). In the main form, the following function initializes the class (clsMail is a private var in the main form) and calls the logon method:
|
There are two constants used for the profile name and the password. This is the profile you created for the domain user, which your service uses to log on to NT. Here's the logon method:
|
The catch is in the parameters for the logon method of the session object. Here's the description:
Profilename: | The profilename you created on the target server |
Password: | The domain password of the user you created |
Showdialog: | False |
NewSession: | True (doesn't matter)> |
Parentwindow: | 0 (doesn't matter) |
NoMail: | True (very important setting) |
The NoMail setting is where it can all go wrong. It tells MAPI whether it should start the mailspooler. The default is to start it (NoMail = False). There's one big problem with the mailspooler -- it's not accessible within the security context of a service. (Actually, the mailspooler is started outside any security context. This is a somewhat complex story, but there's a document available through MSDN for the diehards.) Solution: Set NoMail to True. I use a little check function to check whether the session is already initialized. If not, a new session object is created:
|
As mentioned previously, there's a timer control on the main form. I use it to call a method of the mail class (ProcessMessages):
|
This method parses new messages in an Exchange folder. For each new message, it performs types of actions on a SQL Server database -- for example, retrieving information -- and sends results back to the sender:
|
Well, as you can probably see already, the possibilities are endless. At my company, we just built one for guarding both our Web and Exchange servers. This agent polls our clients' servers and checks whether everything is still working. It will notify the correct people if there's trouble. In the new Exchange Server 5.5, it's possible to create agents using server-side scripting. This will probably end the use for mail-reading agents running on Exchange servers. But if you want your agents on a separate server, I can't think of a simpler way to create them. [Readers might also want to explore the Windows NT Resource Kit's SRVANY.EXE, which lets you run any NT application as a service. -- Ed.]
Diderick Oerlemans is an IT consultant and partner in I-Cube BV, a small IT service company located in Delft, The Netherlands. He has more than six years' experience in developing information systems using Microsoft products. He and his team develop all kinds of client/server systems for midsize and large companies in The Netherlands. www.i-cube.nl, Diderick.Oerlemans@I-Cube.NL.