OLE Server Frequently Asked Questions
I have added some new info to the FAQ. Please let me know if this is
helpful information, or am I just wasting bandwidth and your time.
Thanks.
Author: Rick ClarkOLE Server Frequently Asked Questions
Compiled and Written By Richard D. Clark
Contributions by Joel Shafer and Robert Barraza
Last Updated 09/17/1996
This FAQ covers some topics of OLE servers that have caused confusion
for new programmers trying to create and use OLE servers and OLE
automation. This document is an attempt to clarify some information
and to create a single repository of information for this new area of
programming. This is by no means an exhaustive compilation, but
rather a quick answer to some common questions and pointers to other
more detailed information.
- What is an OLE server and OLE Automation?
- What is meant by in process and out of process OLE servers?
- What does the Public property on a class module do?
- What does the Instancing property on a class module do?
- What is Remote Automation?
- What is a pool manager and why would I need one?
- Does VB OLE support callbacks?
- How could I create an asynchronous client/server system?
- What data types can be passed to a remote OLE server?
- Can I provide automatic failover to another server node, if the
current server node fails?
- Can a VB 3.0 program call a 4.0 OLE server?
- What is the OLE server search order for 32 and 16 bit OLE
servers?
- How do I create a TLB file for my public OLE server.
- How do I add help strings to my OLE server methods and properties
like I see in the Object Browser for other references?
- How can I tell if my application was launched as a stand alone
program or as an OLE server?
- How do I hide the Automation manager?
- How do I pass a user defined type to an OLE server?
- Why is the terminate event not fired in my OLE server, when I end
my application?
- How do I pass parameters to the Initialize event of a class?
- Can I call a 16 bit OLE server?
- How do I set up a remote automation server and client?
- Should I set properties on a remote OLE server or pass
parameters?
- What is the difference in using ByRef and ByVal calls to a remote
OLE server?
An OLE server is essentially an application that exposes, or makes
available, to another program its Properties and Methods. OLE server
applications range from Microsoft Excel and Word to an application
that Joe programmer found useful and is releasing to the public use.
In order for an application to be an OLE server, it must conform to
the OLE 2.0 standards and properly expose the necessary properties and
methods. This is called the OLE application interface.
OLE Automation is the means by which a client accesses the properties
and methods of a server. Automation can be both local and remote,
depending on the needs of the client application. In the Visual Basic
(VB) programming environment, OLE automation is built into the
language. Object variables are the foundation by which you can
access the OLE server interface. In VB, by instantiating (using the
SET statement) an object that references an OLE server, you have
access to the published properties and methods of the server. You
have created an object in your client application that is directly, or
indirectly (via a pool manager of some sort) connected to the OLE
server application.
OLE servers and OLE automation are the foundation for the component
philosophy of software development. By creating and utilizing OLE
servers, a set of reusable components can be created that can be used
in a wide variety of programs, including off-the-shelf products.
OLE is also the foundation (for VB as least) of the three-tier method
of data access. The concept, greatly simplified, is the idea of
encapsulating the business rules in a middle tier of a client/server
system in order to facilitate maintaining working applications in a
changing environment.
Tier one holds the client side application, tier three holds the
database and tier two could be a set of OLE automation servers that
broker requests from the client applications to the database. If the
business rules change, then theoretically, only the middle tier needs
to change. The client doesn’t know or care about the changes and
neither does the database. If the database changes, the middle tire
may need to change, but no change would be required in the client
applications. The client will simply instantiate the server in its
application and if the published interface has not changed, no change
is necessary in the client.
An in-process OLE server is a Dynamic Link Library (DLL) that runs in
the same process space as the client application. Out of process
servers are EXE files that run in their own address space. In process
servers are usually faster than out of process servers. In process
servers are created by selecting the Make DLL function from the File
menu in the VB IDE. Out of process servers are created using the Make
Exe menu item. In process servers can only be created with the 32 bit
version of Visual Basic. Furthermore, you cannot access a 32 bit in
process server from a 16 bit VB program (see VB help file topic: OLE
Controls Interoperability for 16- and 32 bit Platforms).
A client application currently cannot access an in process remote
automation server (although with Network OLE, we may be able to do
this). A client will need to access a remote out of process server
which would in turn than access the in process server.
Setting a class module’s Public property to TRUE, enables the class
properties and methods to be visible to any program. You would set
this property to TRUE if your server will need to be visible to other
applications; as in the three-tier example.
Setting the Public property to FALSE will create a private OLE server
that will only be visible within the current project. You would use
this setting to modularize a projects with classes, but not need to
create a public OLE server.
This class module property has three settings:
0: Not creatable. This setting is for a private class module.
1: Creatable single use. This setting is for a public OLE server and
is used if you want to have an instance of the server running for each
application that is accessing the server. That is, if two client
application instantiate the OLE server, two copies of the OLE server
will be created.
2: Creatable Multiuse. This setting for a public OLE server is used
when you want only one instance of the server to be created. The
first request to the server will load the server into memory, and
subsequent requests will return pointers to the loaded server.
Note on server types:
Only one application can use a server at any time. Therefore if two
requests are made to a multiuse server, one request will be blocked
until the first request has finished processing. If many applications
are requesting the services of the server, blocking can become a
problem.
On the other hand, by loading multiple instances of the same server,
when using single use, resources can be quickly exhausted. See the
question 6 (pool manager) in the FAQ for more information.
Remote automation is simply an OLE server that does not reside on the
client application’s computer. It is located on another machine
accessible via a network. As far as building the server, there is
nothing special that needs to be done. A local OLE server can also
function as a remote OLE server. No code changes are necessary. (Of
course, since the server machine needs to have the Automation Manager
running, and this will only run under Windows 95 or Windows NT, then
the OLE server should be compiled as a 32 bit application). As far as
the client application is concerned, it does not know or care that the
OLE server is being accessed remotely.
The client will load the Automation Proxy and the server needs to run
the Automation Manager. The client finds the particular server,
local or remote by looking at the information that is stored in the
registration database. When the server is registered on the client,
its location is registered so the client will know where to connect to
the server. It is also possible to change the server information in
the database with the Client Registration utility (see Client
Registration Utility topic in the VB help file) and the Connection
Registry utility (see Remote Automation Connection Registry APIs
(ReadMe) topic in the VB help file); but there must only be one
registry entry. Multiple server entries are not allowed.
You can also catalog all the servers using the included Component
Manager.
The Setup Wizard will include the necessary files for both the server
and the client and register all the necessary information in the
registration databases. See Chapter 7, Implementing OLE Servers in the
Building Client/Server Applications with Visual Basic manual.
Pool managers are used to manage a collection of single-use OLE
servers. As previously stated, multiuse OLE servers are loaded once
into memory and then shared among many applications. When the work
load increases, the blocking of clients can progressively become a
problem. On the other hand, creating an unlimited amount of single
user OLE servers can exhaust system resources. It also takes time to
load the servers into memory, so there is some startup performance
penalties.
The middle ground is to create a program to manage a collection of
previously loaded single use servers and then parcel them out as
needed by clients. If the demand is greater than the supply, the pool
manager turns down the request. The pool manager is a program you
have to create. There is no built in pool manager provided in Visual
Basic. Yet, because it is a created program, a great deal of
customization can be included into the program. For example, file
logging can be done, security can be implemented and resources can be
carefully monitored. See question 8 for an asynchronous server
discussion.
The enterprise edition of Visual basic includes a pool manager sample
program. Look under samples\remauto\poolmngr.
Yes. There is an example of this in the VB samples subdirectory:
samples\remauto\callback. To set up a callback system, not only does
the client have to create a server object, but the server must create
a client object to provide a channel for the callbacks. Simply
provide in the server, a method that creates a client object so that
the exposed methods of the client are available to the server.
Whenever the server needs to notify the client, the server uses the
client’s exposed methods to return information back to the client.
This can be a straight code method, or as in the case of the above
example, a control on the client system.
Remote callbacks can only be done with 32 bit operating system
clients. See article Q143259 in the MS Knowledge Base. In a callback
situation, the client is acting as the server and the server is acting
as the client. In this case, the Automation Manager will need to be
installed on the client to broker this request. Since this will only
operate under 32 bits, i.e., Windows 95 or Windows NT, you cannot have
a 16 bit OS client, therefore the client application should be
compiled as a 32 bit application.
This could be easily done via the Pool Manager concept (see question
6). Add to your pool manager a queuing scheme that could receive a
request from a client, add the request to its work queue, notify the
client of the queued item and let the client disconnect. The pool
manager than would run the request at a predetermined time, for
example, or when resources permit .
The data types accepted via the Remote Automation’s marshaling support
are byte, boolean, integer, long, single (real), double, currency,
date, object, string, variant and arrays of the mentioned types.
However, using variants as the OLE data types will keep your public
interface stable and not impact your client applications, if they were
written correctly.
For example, a VB screen is updating a table in a database and passes
all the values to the OLE client as strings. The database changes
from SQL server to Oracle and the data types of the tables change.
This change does not impact the client at all since it is passing the
data as strings. The OLE interface doesn’t need to change since it
uses a variant data type. The only change to the system then, is the
conversion and validation routines in the server to accommodate the
new data types. In fact, if the conversion routines are in a separate
OLE server, then the overall system doesn’t change at all, only the
one OLE server that handles the conversions.
You cannot pass User Defined Types to an OLE server. See question 17
for suggested workarounds.
No, since a server has to be registered on the client. There is no
automatic switching to another server if a node happens to fail.
However, since you can dynamically change a server location using the
Remote Automation Connection Registration Utility, you could possibly
create a monitor that could switch a server if necessary. The
validity of this idea depends on the various factors of the system and
the type of network that is installed.
MS Knowledge Base Q138139
Yes. You must use the CreateObject verb. For example:
Dim obj as Object
Set obj = CreateObject(MyServer.MyClass)
You cannot call an in process server (see question 2). You cannot
return an array data type to VB 3.0 nor can you use the rich error
information (see VB 4.0 Err.Raise), since these are not supported in
VB 3.0.
MS Knowledge Base Q138064
Search Order for 32 bit Client
- 32 bit in process server.
- 32 bit out of process server.
- 16 bit out of process server.
Search Order for 16 bit Client
- 32 bit out of process server (on a 32 bit OS).
- 16 bit out of process server.
MS Knowledge Base Q153569
When you create your OLE server and compile the server into a DLL or
EXE, select 'Options' on the file dialog, then make sure the check box
labeled 'Remote Server Support Files' is checked. This will create a
*.VBR file and a *.TLB file.
MS Knowledge Base Q149047
With the OLE server class module loaded in the VB IDE, select
View.Object Browser (F2). This will display the Object Browser
Dialog. Select your project name (i.e. Project1) from the
Libraries/Projects drop down. The left hand list will show the
classes and modules in your project. Click on your OLE server class
module. All the methods and properties defined for your class will
displayed in the right hand list. Click on a method or property and
click the Options button. Enter the description in the Description
text box and then click OK. In the Object Browser dialog, the
description now appears under the method/property definition along the
bottom of the dialog. These strings are saved in the class module
file.
MS Knowledge Base Q129739
Use the App.StartMode function. If the function returns
vbSModeStandalone, then the application was started as a standalone
application, otherwise it was started as an OLE server application.
Example:
If App.StartMode = vbSModeStandalone Then
Msgbox "Application is running stand alone."
Else
Msgbox "Application is running as an OLE server."
End If
This information can be found in article Q138067 in
the MS Knowledge Base. You
will have to modify the registration database in order to specify a 'Hidden' run
mode so that the manager will run without a visible interface.
Once it is hidden you will need to use a system utility like Pview to
terminate the program.
MS Knowledge Base Q129868
You cannot directly pass a udt to an OLE server, so you have
indirectly pass the information.
There are two ways to do this: First, pass each element of the UDT as
separate elements. Second, you can create an udt class, i.e. a class
module that contains properties that replicate the elements of your
udt and then use property procedure to reference the individual
elements. You could also replicate a udt array by using a class
collection, with each object in the collection your class udt.
MS Knowledge Base Q129885
If you use the END statement in your program, the terminate events of
objects will not be fired (except under NT). In order to have the
terminate event fire, you need to set the object reference to Nothing.
Set obj = Nothing . This will cause the terminate event to fire.
MS Knowledge Base Q138065
You cannot pass parameters to the initialize event, so you have to
write your own 'Create' method. You can then call the Create method
passing any parameters you need to object. You should add a private
Boolean flag so that you can be sure that the Create method has been
properly called when the other class methods are referenced.
This is a confusing point, since terminology here gets in the way. As
previously stated, the server machine must be running a 32 bit
environment: Windows 95 or more probably, Windows NT. The sever
machine must have the Automation Manager running, and this program is
32 bits only. The OLE server, that is the program, can be compiled as
16 or 32 bits. (I have tested the scenario of 16 client to 16 server
with no problems). However, it is silly to compile a 16 bit
application that will only be able to run in a 32 bit environment.
Therefore, the OLE server should be a 32 bit application.
The following is a step by step tutorial on setting up a remote
automation server and client.
I will be using the two sample programs helo_svr (server) and helo_cli
(client) located in samples\remauto\hello of the VB subdirectory. The
process described here will be a manual set up for illustrative
purposes. The Setup Wizard automates this process when you create
distribution disks.
- Load the OLE server, helo_svr project and select File-Make EXE to
compile the program. On the File-Save dialog, click the Option button
and make sure the “Remote Server Support Files” check box is checked.
This will be needed by the client. Compile the program.
- Install the program on the server machine along with the Remote
Automation Manager. If you are using the Setup Wizard, be sure the
'Install Remote OLE Automation...' check box is checked so that the
needed files are included. If you are running the server on the
development machine, then setup is not necessary for this
demonstration.
- On the server machine, run the RemAuto Connection Manager. In the
left pane select the entry HelloProj.HelloClass. Select the Server
Connection tab and enter the appropriate information in the Network
Address, Network Protocol and Authentication Level fields. The
settings I used were:
- Network Address: \\rclar9 (machine name).
- Network Protocol: Named Pipes.
- Authentication Level: Default.
Click the Client Access tab and select 'Allow All Remote Creates'. In
an actual deployment, this will need to be whatever is required by the
business.
On the Server Connection tab, click the Apply button to set up the
server. Run the OLE server and the Automation Manager on the server
machine. The OLE server is now ready.
- Compile the client project, helo_cli.
- Install the client on the client machine. If you are using the
Setup Wizard, on step 4 click the 'Add OLE servers' button and then
select the helo_svr.vbr file you created when you compiled the server.
An additional dialog will be displayed. Fill out the appropriate
information that you entered when you set up the server, and continue.
- Setup Wizard will register the client on the target machine (if
you used Setup Wizard) but I will go over the process to illustrate
the necessary steps. You will need the helo_svr.vbr and helo_svr.tlb
files that were created when you compiled the server. On the client
machine, run the CLIREG16 (16 bit) or CLIREG32 (32 bit), which ever is
appropriate, passing the proper parameters. These programs are in
\clisvr of the VB subdirectory.
Page 137 of the 'Building Client/Server Applications with Visual
Basic' lists the all the parameters of the registration utility. I
found that I needed to pass both the TLB and VBR file in order for the
client to work properly. Page 135 in the same manual, lists the
network protocols and the representative clireg string. If you don’t
specify the server or protocol, the clireg program will prompt you for
the information.
- Run the helo_cli program. On the server machine the Automation
manager will indicate 1 connection to 1 object.
Note: I ran this process successfully on one machine, in addition to
two separate machine. Obviously, remote means more than one machine,
but the concepts still work even if you only have one machine
available. You can verify that the system is indeed using the remote
automation tools by closing the Automation Manager and running the
client program. You should get a 'No more endpoints available...'
error.
The difficulty with this process, I found, is the network protocols.
You have to be sure that you specify the correct information or the
client will not be able to find the server. Also, be sure that the
OLE server is running, or you will get an 'OLE Automation server
cannot create object' error.
It is always faster to pass parameters than it is to set individual
properties. Use optional parameters and set the necessary properties
in the beginning of the code module. This will reduce the number of
calls needed to server and improve performance, at the cost of some
additional code in the module.
Using a ByRef actually passes a data pointer to a Function/Sub, so it
is much faster for in-process subroutines. It is slower though, on
remote servers, since the data must be copied twice. Since a pointer
cannot span across machines, OLE must copy the value to the target
machine, and then copy the value back to client, since it has no way
to know if the data was changed.
Using ByVal though, the data is copied once to the server, as in a
normal Function/Sub call. This reduces the cross-network calls, and
improves performance.
Sources Used in this FAQ:
- OLE Remote Automation: Synopsis and Analysis. The Cushing Group.
Copyright 1995, The Cushing Group. http://www.cushing.com/.
- Creating OLE Servers with Microsoft Visual Basic. Craig Lokken,
Mary Anne Kobylka, Microsoft Corporation. Copyright 1995, Microsoft
Corporation. http://www.microsoft.com/
- Building Client/Server Applications with Visual Basic. Microsoft
Corporation. Copyright 1995, Microsoft Corporation.
- Professional Features, Creating OLE Servers. Microsoft
Corporation. Copyright 1995, Microsoft Corporation.
- Visual Basic Help File. Microsoft Corporation. Copyright
1991-1995, Microsoft Corporation.
- Microsoft Knowledge Base. Microsoft Corporation. Copyright 1995,
Microsoft Corporation.
More information can be found at:
http://www.microsoft.com/vbasic/vbfeatur/remauto/REMAUTO.HTM
http://www.microsoft.com/vbasic/
Please contact Richard Clark (clarkr@flash.net) for
additions or errors in this document. The document is provided as is, and is used at the
risk of the reader.
|