The Remote Automation Enigmas: When, Why, and How

Ken Bergmann
Microsoft Developer Network Technology Group

November 15, 1995

Revised: July 1996 by Mark Gendron (notes about DCOM and a clarification of the definition of three-tiered architecture)

Click to view or copy the files for the REPGEN sample application.

Click to view or copy the files for the REPGNTST sample application.

Abstract

This technical article illuminates the details of the Remote Automation architecture as it exists today. It also discusses the different issues involved in the construction or deployment of Remote Automation solutions. This article assumes a solid knowledge of the Microsoft® Visual Basic® language, and a firm understanding of the OLE Automation model and usage.

Remote Automation: Up Close and Personal

In the last few months, I have noticed a phenomenon. And I don't mean the World Wide Web. I am talking about the inundation of client/server developers with a lot of hype about three-tiered architectures and distributed processing. At the heart of this blizzard of information is a new buzzword: Remote Automation. At developer conferences, on the Net, in press articles, the mantra is: "Remote Automation will help you. Use Remote Automation in your system and distribute the load. Remote Automation is your friend."

Take a break, folks. Remote Automation won't work for every system; it will only help in a very small percentage of situations. The trick is understanding when it will help, and then milking it for all it's worth.

This article covers three main topics:

The Details of Remote Automation

Here are some of the specifics about the components and what they do for each part of the system.

Remote Automation vs DCOM

Remote Automation is the model of choice for 16-bit platforms or for 32-bit platforms that do not implement the Distributed Component Object Model (DCOM) protocol. Microsoft Windows® 95 is an example of a 32-bit platform that does not implement DCOM. Remote Automation is also the "migration mechanism" of choice from platforms (either 16-bit or 32-bit) that do not support DCOM, to those that do support DCOM.

DCOM is "an application-level protocol for object-oriented remote procedure calls useful for distributed, component-based systems of all types." A working paper that describes DCOM in greater detail may be found at http://www.microsoft.com/oledev/olecom/dcomspec.txt.

Server Components

Figure 1 shows where the pieces go in your system.

Figure 1. How the components fit into the system

Here are the system requirements for Remote Automation today:

How to Set Up the Remote Automation Components

As should be apparent from Figure 1, you need to have the Remote Automation proxy running on the client machine and the Remote Automation Manager running on the server machine.

Following are the steps to get an existing system with both sets of source code (client and server) up and running remotely. First, the steps to create a client installation package:

  1. Open the server's project file in the Design Environment. Click the Tools/Options menu item. Select the Project tab. Ensure that OLE server is checked in the StartMode frame. Click OK.

  2. Click the File/Make EXE menu item. Click the Options button. Ensure that the Remote Server Support Files option is checked. Click OK. Click OK again to build the executable.

  3. If you already have an executable for the client, go to the next step; if not, build this executable now.

  4. Open the Visual Basic 4.0 Setup Wizard. Enter the path and file name for the project file for the client source code. Choose any options you want here. Click the Next button. If you chose to build a new executable, this happens now. Continue with the next step when the Setup Wizard is at Step 4.

  5. The Setup Wizard should be at Step 4. If your client application uses any local automation servers, these should be listed in the list box. Click the Add OLE Servers button.

  6. You should be at a file navigation dialog box. Change the Files of Type combo box to display Remote OLE Servers (*.vbr). There should be a .VBR file in the same directory as the server executable. Select this file and click OK.

  7. You should be at a Remote OLE Server Details dialog box. Enter the name of the server machine in the Network Address text box. Select your primary network protocol from the Network Protocol combo box. Select the authentication level you want from the Authentication combo box. Click OK.

  8. Continue through the Setup Wizard until you reach Step 6. Choose Install in Application Directory in the Deployment Model frame. Ensure that the check box for Remote Automation support files is cleared (not checked). Click the Next button.

  9. Go ahead and finish the Setup Wizard. When done, you will have a complete client installation package. Run the SETUP.EXE that was created to install the client software on a client machine.

To create an installation package for the server executable:

  1. Open the Visual Basic 4.0 Setup Wizard. Enter the path and file name for the project file for the server source code. Select any options you want here. Click the Next button. If you chose to build a new executable, now is the time to do so. Continue with the next step when the Setup Wizard is at Step 6.

  2. When the Setup Wizard is at Step 6, select "Install as an OLE Automation shared component" in the Deployment Model frame. Ensure that the box for Remote Automation support files is checked. Click the Next button.

  3. Go ahead and finish the Setup Wizard. When done, you will have a complete server installation package. Run the SETUP.EXE that was created to install the server software on a server machine.

At this point, you should have installation packages for both your client and your server. Install the software on the respective machines. The server installation should create a Remote Automation Management Folder or Group. The two icons created in this folder or group can be used to set up and administer all of the Remote Automation services for the server machine.

Run the Automation Manager application. This is the component to which the clients will connect. It will pass on client requests to the OLE servers that are local to it. Now install the client software on a client machine. During installation, information about the remote server is inserted into the registry of the client machine.

Peripheral Issues

These are the basics, but there are some other issues involved. If you want the user at a client machine to have control of the server name or network transport that is used to connect to the server machine, you will also need to install RACMGR32.EXE to the client. Setup Wizard does not currently do this for you. For an unattended system, there must be a facility to ensure that the Automation Manager is started when the system reboots. For situations where the network address of the server machine changes, you will need to provide update mechanisms for the clients to run on their local machines.

These issues bring up the subject of CLIREG32.EXE, a handy tool included by the Setup Wizard while creating a setup package for client installation. Its purpose is to modify the registry of a client machine to include the necessary entries for the client to perform Remote Automation against the server. This utility accepts the following parameters:

This is essentially the same information that can be viewed and modified using RACMGR32.EXE. The difference is that RACMGR32.EXE requires the entries for the type library to already exist in the registry, whereas CLIREG32.EXE will install the entries if they don't exist. Using the application's command-line interface, it would be very easy to create a batch file to call this application and handle the registration and configuration in one step. This would be ideal for upgrading clients when a server name or OLE server type library changes.

How to Build a Remote Automation Server

Building a Remote Automation server is really not much different from building any other automation server—or so it appears at first. Indeed, implementing Remote Automation servers is no different from implementing any other automation server.

However, the design of Remote Automation servers presents many issues that can directly affect the architecture of a Remote Automation server. Many of these issues are not nearly as critical to the design of local automation servers because the cost involved in moving data locally is so much less than moving it remotely. With that in mind, here are some things to remember throughout this section. To be able to talk about how to build a Remote Automation server, I included the REPGEN and REPGNTST samples so that I can point out some important considerations that went into the server design. This server is a learning tool, and certainly not intended as a real product. But for the sample to be effective, it needs to serve a purpose and show some real functionality. I use this example to show the basics of building an automation server to help you focus on the real issues and not get bogged down in the details of the class design.

Designing the Server Interface

The samples have both server (RepGen) and client (RepGenTest) components. The server exposes, among other things, a list of reports from Microsoft Access for Windows 95. This server provides the basics of a network printing utility. It allows the user to print reports without having to have Microsoft Access loaded on the user's machine. This is what my class definition looks like:

Private AccessApp   As Access.Application
Private sDBName     As String
Private sCurrentRep As String
Public fPhaseTwo    As Boolean

Public Property Get DBName() As String
Public Property Let DBName(ByVal sVal As String)

Public Function GetReport(ByVal sRepName As String) As Object
Public Function InitializeAccess(ByVal sDBName As String) As Boolean
Public Function ReportList() As Variant
Public Sub PrintReport(Optional fAsync As Boolean)
Private Sub ReportPrint()
Public Sub TerminateAccess()

Notice that I don't expose the application object and that I have limited the scope of all variables as much as possible. In the case of the fPhaseTwo variable, I don't need property procedures because there isn't much to it and I wanted to minimize this code as much as possible. Remote servers should always be written as tightly as possible.

Object References

I always try to give users of my server as much power as possible without slowing down the access mechanisms, so I am just providing the client with a reference to a report object. Essentially, once users have this reference they can do whatever they want with it. Note that this isn't always the best idea; if it weren't making a point for me, I would probably remove the object reference on the GetReport routine. The following lines of code from the function show why:

sCurrentRep = sRepName
AccessApp.DoCmd.OpenReport sCurrentRep, acPreview
Set GetReport = AccessApp.Reports(sCurrentRep)

There are two reasons I wouldn't usually return an object reference like this. First, the Report object I am returning is a user-interface construct (window). This generally isn't a good idea because you can't guarantee the life of such a window. Specifically, in this case, I can't be sure what the users are going to do to it; they could easily freeze the interface on the remote machine.

Second, the reference returned from the function will require a cross-process call every time the user accesses the object. Cross-process calls are very expensive for an application, especially when the processes are on two different machines.

Notifications Between the Client and the Server

For those who would like to understand what callbacks and asynchronous processes look like in code, the PrintReport routine shows one mechanism used to disjoint processes:

Public Sub PrintReport(Optional fAsync As Boolean)
If IsMissing(fAsync) Then
    ReportPrint
Else
    If fAsync Then
        fPhaseTwo = False
        tmMain.Enabled = True
    Else
        ReportPrint
    End If
End If
End SubEnd If

In this example, I didn't use a standard callback routine. Instead I implemented a two-phased commit. The point is this: Don't always assume that standard implementations will provide the most efficient support for the features in your system. If you don't need the overhead of implementing full callback routines, don't use them. In this example, I wanted the user to have the choice of printing reports either in real time or asynchronously. A two-phased commit allows me to provide this with almost no code duplication. Here is what the synchronous process flow would look like:

Figure 2. Synchronous (real-time) process flow

Here is what the asynchronous process flow would look like:

Figure 3. Asynchronous process flow

You can see that including the flag (fAsync) makes it possible for the client to request a report to be printed asynchronously. The client can have the report printed in real time simply by omitting the flag. Of course, I could just as easily have reversed these conditions and required a flag for printing synchronously and no flag for printing asynchronously; it would depend on what I expected the normal usage of my server to be.

The other important point to glean from this concerns the implementation of a local callback routine. Many developers consider callbacks to be useful only in distributed applications. As Figure 3 shows, local callback routines can be very effective in delegating the normal processes that exist in a client/server system. For more information about callback routines and process linkages, see the next section, "Remote Automation in Perspective."

Remote Automation in Perspective

The object of this section is to understand, at a fairly high level, the decisions that go into particular implementations of Remote Automation servers. It also attempts to tie in the benefits or shortcomings of Remote Automation with the issues faced in online transaction processing (OLTP) client/server development today.

The Simple Case

The most basic use for Remote Automation is fairly trivial. A Remote Automation server is instantiated on a machine by a non-local client. The non-local client gives the server information, which it uses to do some form of processing. Once the processing is completed, the server returns control to the non-local client. The server is then released by the non-local client. Here's what this looks like:

Figure 4. Simple use of Remote Automation

Here are some cases in which you might use this:

This list is not very extensive and most things on this list have no reason to be distributed. This kind of distribution just doesn't have much impact on the OLTP solutions prevalent today.

Callback Routines and Asynchronous Processing

The next most complex use for Remote Automation is still pretty basic, but now the system can operate asynchronously. In this case, the client passes a callback reference to the server before requesting the server to commence processing. The server takes the data and the callback handle, and returns control to the client by exiting the routine. It then wakes up on its own, processes the data, and executes the callback method of the callback object on the nonlocal client.

Figure 5. Using Remote Automation for callback routines

The classification list and the performance numbers for this approach are the same as above when the client is controlling the server. The difference is that the client machine may be active while the server is processing. This approach has some other subtleties that are not relevant at this level of discussion. Suffice it to say that this approach usually achieves only the smallest of performance gains and the implementation can be tricky at best.

The Three-Tiered Model

The most common use for Remote Automation is for controlling a server that proctors services from a set of nonlocal servers to a set of nonlocal clients. In this case, there are at least three different machines that communicate, theoretically, via Remote Automation.

Note that the term "three-tiered" is a logical concept and is not meant to describe a physical implementation. "Three-tiered" refers to a logical separation of User Services, Business Services, and Data Services in a system design. The actual architecture being illustrated here could best be described as a "three-tiered model implemented using three machines." The distinction may seem trivial, but it is not. A system may be implemented using three machines, and yet not represent a "three-tiered" model. In such a case, referring to the system as "three-tiered" would be misleading.

Figure 6 shows the communication paths between the machines and their physical relation to each other.

Figure 6. Communication in the three-tiered model

Some reasons to use this approach might be:

Summary

So now you have had a look at the three main types of Remote Automation. If you understand them, it should not be hard to choose the right implementation for your system. But remember the discussion about implementing callback routines ("Notifications Between the Client and the Server"): The best-case solution might not follow standard rules of implementation. Instead, it might require innovative use of common technologies.