KnowledgeBase Archive

An Archive of Early Microsoft KnowledgeBase Articles

View on GitHub

Q157049: HOWTO: Debug Remote Automation Servers in Visual FoxPro 5

Article: Q157049
Product(s): Microsoft FoxPro
Version(s): 
Operating System(s): 
Keyword(s): kbcode kbinterop kbAutomation kbvfp500 kbvfp600
Last Modified: 03-AUG-1999

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Visual FoxPro for Windows, versions 5.0, 6.0 
-------------------------------------------------------------------------------

SUMMARY
=======

This article discusses general directions on how to debug remote server
applications.

MORE INFORMATION
================

Visual FoxPro 5.0 allows you to create remote OLE Automation servers. Unlike
servers deployed locally, which can either be an .exe file or a .dll file,
remote servers must have an .exe file extension. One of the advantages with .exe
type servers is that they have their own event loop, so you can process events.
However, in a typical remote situation, your server is non-visual (typically a
business object in a three-tier situation).

Debugging your .exe servers should be straight forward. For the most part, you
should be able to test your servers locally before deploying them remotely. Most
of the servers run the same in both situations. The approach you should take in
creating and debugging a remote server is as follows:

1. Create your server as an internal Visual FoxPro class. Assuming you have a
  project called Books, which has a custom class called taxes that calculates
  the state/province sales tax for your mail order book sales business, you
  might have your class loosely structured as follows:

        * TaxLib.PRG
        DEFINE CLASS taxes AS custom
        PROCEDURE gettaxes
           LPARAMETER cState
           DO CASE
           CASE m.cState = "CA"
             RETURN .08
           CASE m.cState = "WA"
             RETURN .07
           CASE m.cState = "NY"
             RETURN .10
           OTHERWISE
             RETURN 0
           ENDCASE
        ENDPROC
        ENDCLASS

  Your application can test this class within Visual FoxPro internally with code
  similar to the following:

        cState = "CA"
        nBookPrice = 19.95
        SET PROCEDURE TO TaxLib    && can also use SET CLASS
        oTaxes = CreateObject("Taxes")
        nBookTax = oTaxes.GetTaxes(m.cState) * m.nBookPrice
        ? "Book total: "+ALLTRIM(STR(m.nBookPrice+m.nBookTax))

  The advantage here is that you are working within the Visual FoxPro
  development environment so you can take advantage of the debugger for common
  errors such as "Syntax Error."

2. Change your class definitions to OLEPUBLIC and test locally. Theoretically,
  you have already debugged for most of the common errors. Now, you want to
  test the class as an OLE Server. In order to do this, update the class
  definition to make it OLE Public and rebuild the project, selecting the Build
  EXE option. The following shows this using a class defined in a .prg file:

  Change:

        DEFINE CLASS taxes AS custom

  To:

        DEFINE CLASS taxes AS custom OLEPUBLIC

  NOTE: If you are using a visual class created in a .vcx file, you would go
  into the Class Info dialog box to select the OLE Public check box.

  Once you have created your OLE Automation Server, you can update your test
  code as follows (notice that you no longer need a SET CLASSLIB or SET PROC
  statement--the class is automatically registered in the Registry as an OLE
  class):

        cState = "CA"
        nBookPrice = 19.95
        oTaxes = CreateObject("Books.Taxes")
        nBookTax = oTaxes.GetTaxes(m.cState) * m.nBookPrice
        ? "Book total: "+ALLTRIM(STR(m.nBookPrice+m.nBookTax))

  You should not encounter many problems beyond step 1; however, there are a few
  things to look out for. Since the OLE Server uses the run-time version, not
  all the language is supported (especially some of the user interface and
  designers). Make sure you avoid commands that do not work with the run-time
  version (these are documented in the Visual FoxPro Professional Features
  Guide, under "Distributing Applications").

3. Deploy the OLE Server remotely. You have already created your OLE server.
  Now, you need to register it remotely. The easiest way to do this is through
  the Remote Automation Connection Manager (RacMan). RacMan allows you to
  switch an existing OLE Server, which you already have registered locally, to
  being registered remotely. In order to do this, make sure your remote machine
  has that server installed and registered properly and access rights are
  properly made available to the client. Finally, to create an instance of that
  server, you must be running DCOM (Distributed COM or Network OLE) between
  your machines (NT 4.0 or later) or be running the Automation Manager program
  that ships with Visual FoxPro on the server. See Visual FoxPro documentation
  for more details on setting up for remote automation and using RacMan.

  Many of the problems associated with using remote automation servers are not
  with the servers themselves but rather configuring them properly with valid
  network address, protocol and access rights.

  The biggest concern at this stage is checking for wait states that might stop
  the client. For example, a MessageBox() call that brings up a dialog box on
  your server can be closed only when someone manually goes over to the server
  and closes it. Meanwhile, your application is locked in a busy loop waiting
  for the server to complete the command.

Strategies
----------

- Error handlers. Error handling is probably one of the more common problems
  with remote servers. It is imperative that your error handlers avoid using
  dialog boxes that can place your server in a modal state. Your error handlers
  should return an error code (possibly message) to the client for proper
  handling.

  Depending on how conservative you are with your code, you can either check
  after each automation call to the server for an error, or let your error
  routine handle it.

- Wait states. In general, your remote servers should be non-visual. There may
  be extraneous wait state code such as BROWSE, MODIFY MEMO, WAIT WINDOW that
  relies on user input. Make sure to avoid this type of code, which can place
  the client in an endless loop.

- Application object properties. There are several properties you can use in
  your client applications to more effectively handle problems with OLE
  Servers, including the following:

     OLEServerBusyTimeout
     OLERequestPendingTimeout
     OLEServerBusyRaiseError
     StartMode

- Blocking with OLE Callbacks. Visual FoxPro supports the ability for remote
  servers to make OLE Callbacks into your clients. An object reference on the
  client can be passed to a remote server. The remote server can then call a
  method or set a property on this object. When this happens in a remote
  situation, the Automation Manager is automatically launched on the client
  machine. A common problem with OLE Callbacks is when you have the client pass
  an object reference to a method on the server. This method then tries to make
  a callback on that object. A blocking problem occurs (Error: Call was
  rejected by callee) because the client is waiting for the method to complete
  execution even though the server is trying to call back into the client. Here
  is a simple example:

        * Client code
        x=create("myproj.myserver")
        y=create("form")
        x.test(y)      &&generates error because of blocking

        * Server code in project Myproj
        DEFINE CLASS myserver AS custom OLEPUBLIC
          PROCEDURE test
            PARAMETER oForm
            oForm.Caption = "Hello World"
          ENDPROC
        ENDDEFINE

  There are a number of ways to successfully handle OLE Callbacks. One is with
  the use of Timers (see the Pool Manager sample located in Samples\Servers).

Common Errors with Remote Automation
------------------------------------

- Error: OLE error code 0x800706d9: There are no more endpoints available from
  the endpoint mapper.

  Possible causes: Automation Manager/DCOM not started (running) on server.

  Remedy: If you are using Automation Manager, make sure to launch the program.
  With DCOM, check DCOM documentation for possible problems configuring it. If
  a successful connection is made, the Automation Manager window indicates so.

- Error: OLE error code 0x800706a7: The RPC protocol sequence is not
  supported.

  Possible causes: The Network Protocol specified on the client machine for the
  remote server is not supported.

  Remedy: On the client machine, launch the Remote Automation Connection Manager
  and go into the Server Connection tab. Select a Network Protocol that is
  supported such as TCP/IP.

- Error: OLE error code 0x80070005: Access is denied.

  Possible causes: This is often due to improper client access set on the
  server.

  Remedy: On the server machine, launch the Remote Automation Connection Manager
  and choose the Client Access tab. Make sure the System Security Policy is set
  correctly. If this does not work, try using one of the other Policy options
  such as Allow All Remote Creates.

- Error: OLE error code 0x800706e4: The requested operation is not supported.

  Possible causes: This is often due to improper client access set on the server
  when the System Security Policy is set to Allow Remote Creates by ACL.

  Remedy: On the server machine, launch the Remote Automation Connection Manager
  and choose the Client Access tab. The third option should already be selected
  (Allow Remote Creates by ACL). Make sure The ACL (Access Control List)
  privileges are set correctly to allow for client access via the Edit ACL
  button. If this does not work, try using one of the other Policy options such
  as Allow All Remote Creates.

- Error: OLE error code 0x80010001: Call was rejected by callee.

  Possible causes: A block in OLE Callback.

  Remedy: Make sure that callbacks are made independent of the client's actions.
  Use a timer as in the Pool Manager example.

- Error: Server busy or mousepointer endlessly busy

  Possible causes: This is often due to some wait state in the server such as an
  error dialog box, message box, browse, and so forth.

  Remedy: Avoid using code that requires user input.

- Error: Feature not available.

  Possible causes: Command or function is not available in run-time version.

  Remedy: Do not use these commands.

Additional query words:

======================================================================
Keywords          : kbcode kbinterop kbAutomation kbvfp500 kbvfp600 
Technology        : kbVFPsearch kbAudDeveloper kbVFP500 kbVFP600
Issue type        : kbhowto

=============================================================================

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Copyright Microsoft Corporation 1986-2002.