The new Management Console and New Project Wizard make short work of creating a COM object and running this object through COM from the Web Connection ISAPI extension. For Project generated COM server configuration see Step 5 of the New Project Wizard.

The Server Configuration Wizard is the easiest way to get COM up and running with Web Connection. However, if something goes wrong during installation it's important that you understand what's actually happening when you build a Web Connection COM server. This topic takes you through the manual steps.

If you go through the steps manually for the first installation you need to:

  • Compile the project into an EXE
  • Copy the EXE to the server (could be part of an install)
  • Register the COM object
  • Configure the COM object for DCOM permissions

When to use COM

Since Web Connection can run as a standalone EXE you might ask yourself why bother with COM. After all COM is a little more difficult to set up (although much easier than it used to be) and configure. However, COM operation with WWWC has some distinct advantages:
  • Improved Performance in high volume environments
    COM operation provides better performance under load as it eliminates the message files that are used for file based messaging. Under low load scenarios the difference is minimal but under heavy load COM can significantly improve throughput.

  • COM Servers start automatically
    COM Servers are invoked on the first hit and launch themselves. They do not need to run as services as they essentially become part of IIS. All you need to do is configure the server or servers to load and the first hit will automatically launch it.

  • Administrative Control
    COM servers can be administered entirely over the Web. You can easily start and stop instances, change the count of instances running. You can also update code easily without shutting down the site simply by having Web Connection swap executable files on the fly. You can also see basic statistics of your servers and you can kill and reload individual servers directly through the HTML remote management interface.

  • Crash Protection
    As much as you might try FoxPro servers might crash occasionally. The COM subsystem may get corrupted, your VFP server may simply crash due to a protection fault, or the system may run low on resources causing your VFP servers to terminate unexpectedly. COM operation is controlled through the ISAPI DLL which actually manages the COM server instances and thus can tell if there's a problem. If a call to the server fails due to a GPF of the server not being loaded anymore for whatever reason the original crashed or hung server is shut down and restarted.

The downside of COM operation is that it's more difficult to set up for the first time. Once installed you have to be careful how you build your servers - COM servers are very touchy about mismatched ClassIDs. If you read this topic carefully and follow a few simple rules the process is straight forward, but it is important you that you follow these steps carefully!

No code changes required

COM operation is supported transparently by Web Connection. The wwServer class has a lComObject flag that determines whether the server is running as a standalone or a COM object. As a COM object the call interface to the server is different and output is generated differently than with file based messaging. All of this happens entirely behind the scenes as part of the framework. Your application code doesn't need to worry about whether it's running under COM or as a standalone app as the objects provide you with the right tools to read and write from the appropriate services.

DEBUGMODE in wconnect.h

Before building your COM server it's important that the server is built bullet proof. Make sure everything works properly in file mode before tyring to run in COM mode.

The most important thing is that all error handling be enabled by setting the DEBUGMODE flag in wconnect.h prior to compiling your project. This is vital so that Web Connection's error handlers can kick in on any non-handled error in your application and framework code.

Compiling the server

First thing you need to do is build your project into an EXE file. Web Connection servers can run in the Web Connection pool as Out of Process servers. The pool is managed and Out Of Process servers allow the control necessary to provide crash protection and live code updates which would not be possible with In Process applications.

Note
You can build DLL servers if you like as long as they are hosted through Microsoft Transaction Server - when you do, note that many of the admin features will no longer be functional.

Web Connection makes it easy to build your server interactively using file based messaging and an interactive Visual FoxPro session which allows you to thouroughly debug and test your code. That gets you 99% of the way.

Once the code works with file based messaging follow these steps.

  1. Make sure that your server works without errors in File Based operation.

  2. Modify wconnect_override.h to make sure the DEBUGMODE flag is set to .F.

  3. Open your Server Project file and build it into an EXE file. This will create a COM capable EXE server.

  4. In VFP 8 or earlier, after you've built the project for the first time, go into the Project Info dialog and select the Servers tab. Set the Instancing combo to SingleUse. This is very important!

  5. Test the COM object which should generate some simple HTML:
    o=CREATE("WebDemo.WebDemoServer")
    ? o.ProcessHit("query_string=wwMaint~FastHit")
    
    If you don't VFP on the machine you're installing on you can create a small .VBS script file. Assuming the machine allows running VBScript files and/or you're an Administrator you can use the following script in a .VBS file:
    set oServer = CREATEOBJECT("webDemo.webDemoServer")
    lcHTML =  oServer.ProcessHit("query_string=wwMaint~FastHit")
    MsgBox(lcHtml)
    
    You should see the server form pop up and then some HTML printed to the VFP desktop.

Moving the COM object to the server

If you're building the COM component on the Web server the object is automatically registered and ready for operation.

However, if you build your component on a development machine and then copy the object to the Web server you have to manually register the component from the command prompt:

<yourserver>.exe /regserver

Make sure that at least the Visual FoxPro runtime is installed on the server. See VFP documentation for required files and how to create an install for COM applications using the Setup Wizard.

VFP 6/7 Note:
If you are using VFP 7 or 6 you also need to copy <yourserver>.tlb to the server as these versions do not compile the type library into the EXE.

Once the object has been registered I'd recommend you try to test it on the server as well. If you have VFP installed you can use the code above. If you don't, you can use a VBScript file or any application that contains VBA to test the server using code similar to the code presented in the last paragraph.

Configure the COM object with DCOM

Once the above works you need to configure the COM object properly so that the Web server can instantiate it. Every EXE server on a system must be configured to allow restricted accounts like the Internet Guest Account to access it.

To do this you use the DCOMCNFG utility (part of Component Services in Windows XP/2003 Server and later):

  1. Go to the NT RUN box and type DCOMCNFG.


    Note: this image is for Windows XP and Windows Server 2003. For Win2000 and earlier this dialog looks different and you'll see the list of servers in a plain list.

  2. Scroll through the list and find your server name in the list usually (<yourProject>.<yourproject>Server) or if you used the Fox Project's server naming features the name of the server.
    Note:
    If you have other objects that are marked OLEPUBLIC in your project it's possible that the name of this object will pop up instead as <yourProject>.YourOtherCOMServer.

  3. Once you find your server select it and double click.

  4. Go to the Identity Tab and set the Impersonation to The Interactive User, which is the currently logged on user.

    This sets the server to run through whatever account is currently logged on and makes it possible to have a visible Web Connection server on the desktop. Essentially DCOM creates an Interactive Logon for the current user session and runs the COM Server in your current Windows desktop environment.

    Running without a Windows Logon
    If you want to run without a Windows logon you can't use the Interactive User and you have to use a specific account instead. To do this choose This User and specify a username and password of a specific Windows user account. Make sure this account has the proper rights to run your application, so it can access data files, configuration files, can read script files out of your Web directory and has rights to SQL databases etc. It's up to you to make sure the account you pick has the proper permissions. Generally this account will be some sort of Admin account similar or the same as the Interactive account you use for testing. This account should be a LOCAL account rather than a Domain account.

    Non Interactive Accounts run invisibly
    Note that when you use an account other than Interactive, Web Connection will run invisibly - there will be no server form showing on the desktop. For more information on startup options see Autostarting your Web Connection Server. For testing we recommend that you use Interactive first to make sure everything works before switching to a specific account.

  5. Go to the Security Tab. You should make sure that hte Launch and Access Permissions on this page are set to 'Use Default' which means they are inherited from the Global DCOM settings on the machine. This is the default so usually this doesn't need to be changed.

  6. Ensure Global DCOM Security allows execution. Again this should be set by default so usually you don't need to change these settings, but let's make sure that they didn't get changed.

    Go to the My Computer node of the tree in Component Manager (for Win2000 and earlier this setting can found on the main DCOMCNFG form under the Security tab). Open up this page and find the Access and Launch permissions.

    By default the Web Connection DLL runs under the default IIS Web Server account which is usually SYSTEM, so your COM servers get launched from this account. The actual account is determined by which account IIS or your IIS Application Pool runs under. If you used standard Web Connection configuration tools and setup steps this account is always SYSTEM.

    Find your Web Connection User Account
    When running IIS, Web Connection usually runs under the SYSTEM account, but depending on your version of IIS and your server is configured another account might be in use. To find the account Web Connection runs under, go to the ISAPI Administration page from Admin.asp. On the status page look at the Current Login value which is the account the Web Connection ISAPI DLL runs under. This is the account you should set Launch and Access permissions for.

    Non Default Configurations
    If you are using IIS 5 make sure you run your Web Connection virtual directory in Low Isolation to guarantee SYSTEM account usage. Otherwise you will need to add the IWAM_ account that the medium or high isolation processes use. This applies to IIS 5 only.

    In IIS 6 you can configure the account used to run an Application Pool process. It's recommended that you use the Local System account (SYSTEM) , but you can use the default NETWORK SERVICE or any other account. If you do, make sure you reflect that account here and add it to the Launch and Access permissions. If you use the Wizards Web Connection automatically configures a Web Connection Application pool, sets the Impersonation of the pool to SYSTEM and adds your virtual(s) to this pool. It's recommended you do the same if you manually configure your server. Remember that if you use a non-SYSTEM account.

    If non-System accounts are used make sure the account has rights to READ access in the directory where wc.dll lives (to access wc.ini) and READ/WRITE access in the Web Connection TEMP directory (to write log files).

    Non-IIS Web Servers
    Other Web Servers run under different accounts and the same mechanism can be used to find the operating user account. Apache varies depending on how it was launched. If launched as a service it will use the account the Service is configured under (usually SYSTEM). If Apache is launched interactively it will use the current desktop login.

    Make sure that the SYSTEM account is in the Access and Launch Permission dialogs. Under IIS 6 it's also a good idea to add NETWORK SERVICE just in case you forgot to set the Application Pool to use the Local System account.

    You need to add these accounts to both to the Launch and Access permission dialogs. Once you've set the permissions here you can click OK and exit the server configuration for your COM server.

    (On Windows 2000 and earlier go back to the main DCOMCNFG form, then click Default Security to get to this dialog).

You should now be able to try executing your Web request and see the server(s) popup.

Programmatically configuring DCOM permissions

The above isn't exactly trivial and it's easy to miss a step. For this reason we've provided you some tools that make this easier. On a lower level you can also perform these tasks programmatically either via the commandline or via functions provided by Web Connection.

Note:
All the DCOM configuration options require that the DCOMPERMISSIONS.EXE file from the Tools directory is deployed to the same directory (or the TOOLS dir) of your server.

Using the the Server Configuration Wizard
As mentioned above the Server Configuration Wizard provides a visual UI for preparing your server installation. Step 4 provides you with the ability to register a COM server and set DCOM permissions through the user interface. You'll notice that we're repeating ourselves - the Wizard is the easiest and most reliable way.

CONSOLE.EXE Command Line
You can also use the CONSOLE as a command line utility either from within Visual FoxPro or from the DOS window:

DOS Window:

*** Configure the Impersonation to Interactive
CONSOLE "DCOMIMPERSONATION" "webdemo.WebDemoServer" "Interactive User"
CONSOLE "DCOMIMPERSONATION" "webdemo.WebDemoServer" "SYSTEM"
CONSOLE "DCOMIMPERSONATION" "webdemo.WebDemoServer" "username" "password"

*** Add Launch and Access Permissions  (only necessary if Windows permissions are locked down explicitly)
CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "Interactive User"
CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "SYSTEM"
CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "username"

From the Command window:

DO CONSOLE WITH "DCOMIMPERSONATION","webDemo.WebDemoServer","Interactive User" DO CONSOLE WITH "DCOMIMPERSONATION","webDemo.WebDemoServer","System"
etc.

Using pure code
This maybe useful if you want to build your own installer:

*** Routines are contained in wwutils.prg SET PROCEDURE TO wwutils ADDITIVE SET PROCEDURE TO wwapi ADDITIVE *** Set Impersonation User DCOMCnfgServer("wcDemo.wcDemoServer","Interactive") && Interactive User *** Set Access rights DCOMLaunchPermissions("webdemo.webDemoServer","Administrators") DCOMLaunchPermissions("webdemo.webDemoServer","SYSTEM") DCOMLaunchPermissions("webdemo.webDemoServer","INTERACTIVE")

Note that you have to have DCOMPermissions.exe available in the FoxPath in order for these functions to execute properly! This command block effectively mimicks the DCOMCNFG steps outlined above.

If you do this you may still need to configure the Access and Launch permissions for the server! You still have to add or at least check for the Default Users in the Default Security tab the first time you register a server though!

Setting up the ISAPI extension for COM operation

  • Bring up the browser and go to the Admin page for your application.
  • Startup your server in file based mode to make sure it works correctly. Try a few links.
  • Click on the Edit Configuration Files link. Scroll the top edit box down to the [Automation Servers] section and make sure that the ProgIds for your servers (Server1=|Server2= etc) are correct - they should match the server tests we did before! If not change the values and click on the Save button on the bottom of the form.
    Note that you can have your server run with up to 32 servers simultaneously with servers having the ability to be called on remote machines.
  • You're now ready to switch the server into COM mode. Start by shutting down the file based app.
  • Go to the Admin Page and click on Switch to Automation Messaging. This puts the ISAPI extension into COM mode.
  • Click on one of the links like Show and Manage ISAPI extension then change the Messaging Mechanism to COM.

Click on the Load Servers link to get your server(s) to load. If this succeeds you should see your server popping up on the desktop and you should see the server(s) display in the list now. Now go back to the Admin page and try hitting one of the links to the server - the links should be served from your new server(s).

wc.ini COM configuration options

You can configure the COM servers with a couple of options in wc.ini. A typical section looks like this:

[Automation Servers]
Server1=wcDemo.wcDemoServer
Server2=wcDemo.wcDemoServer
;Server3=wcDemo.wcDemoServer,OFFICESERVER
ServerLoading=1
KeepAlive=1
COMLoadLockout=0

; Set to 1 Apache and other non-IIS Web Servers, and IIS 4 or older
CallCoInitialize=0

Server List
The server list simply contains the server instances that are to be loaded. They should all point at the same type of server. You can load as many as 32 server instances of your object. It's important to understand that all of these server references must point at the same executable - IOW, each server provides exactly the same functionality. To provide a different server with different operations you have to set up another Web Connection project with a separate copy of wc.dll.

Remote Objects
Server3 demonstrates how you can access a COM object on a remote machine by simply seperating the COM object name with the name of the server that you want to run the object on. Note that the object must exist on the remote machine, must be registered and accessible via DCOM from the same user that is running your application locally. The name must follow standard NT server name conventions and can include IP addresses, domain names, netbios names and UNC type names.

Although the option to do this is available and it works, configuration and administration of this feature is complex and there are issues with DCOM remote lifetime management. For more info on this feature and other loadbalancing options see Scaling Web Connection Servers across the network.

ServerLoading
Web Connection's pool manager allows you to run up to 32 instances of your server simultaneously. This flag determines how servers are loaded when requests come in. By default requests are processed by the first available server in the pool manager. If the first is busy the second one is checked - if it's busy the next and so on. This typically means that the first server in the pool gets much more activity than the last one.

If this flag is set to 1 the servers are loaded in round robin fashion. Web Connection will keep track of the last server hit and them move on to the next one. If that one's busy it keeps going around until it finds one that's available. Round Robin works better in high volume environments as the load is balanced across active apps and the servers have some wind-down time between requests.

KeepAlive
There's a quirk in the DCOM subsystem of Windows NT that causes EXE COM objects loaded by a client and idle for more than 8 minutes to unload automatically. This feature was built into DCOM as a crude mechanism for controlling hung servers. The side effect is that it also kills valid, yet idle applications.

For your applications this behavior may actually be useful in order to preserve server resources - you can load a larger number of servers and keep them idle so only one or two in the group will run. However, the unloading that occurs when DCOM yanks the server is very crude as well - it simply terminates your server much like an app that GPFs. This can on occasion lead to corruption of the DCOM subsystem resulting in occasional error messages related to resource exhaustion.

To work around this problem Web Connection includes the KeepAlive flag. This flag forces the Web Connection ISAPI extension to do an extra AddRef() on the server which keeps the server alive indefinitely.

CallCoInitialize
Determines whether CoInitialize is called for COM operation. IIS 5 and later feeds ISAPI threads that already have CoInitialize called and thus it is redundant to call this function again. The value is off by default and should be turned on only if running on IIS 3 or 4 or when running non-Microsoft Web servers.

If you are running Apache or other non-IIS Web Server in COM mode make sure CallCoInitialize is set to 1.

ComLoadLockout
This is a flag that controls whether requests are queued before the Web Connection servers have fully initialized. If this flag is set to 1 Web Connection returns a message to clients that the servers are still loading. This might be required in very high volume scenarios to avoid overloading the request queue on server startup. The default is 0 (off) which simply queues requests until the servers are loaded and then processes them.

Some COM operation tips

  • Watch your ClassIds
    Be very careful when building your servers to a specific Class IDs. If you move the EXE file to a new location then recompile it you will end up with two or more DCOMCnfg references to the server. If you get too many the server may eventually get corrupt. This doesn't hurt operation, but it gets difficult to find the right server in the DCOMCnfg manager. Moral: Always build your project in the same place. If you move to a new machine, copy the project and rebuild it there rather than creating a new project. This guarantees the ClassIDs stay the same.

  • Re-register the server when the TypeLibrary changes
    Normally you can simply copy your EXE server onto the remote server simply by copying the file. But when you change the server's public interface (ie. the <youapp>Server class) by adding properties or methods the type library registration may get out of sync. In this case you should first unregister the old server, then re-register the new server. You should also restart the Web Service because IIS caches the type library and won't detect the new one until restarted.

  • Choose a ProgId that shows up at the top or bottom of the DCOMCNFG List
    Name your servers so that they show up at the top or bottom of the DCOMCnfg Server list - that way you can quickly find it and change the settings.

  • Use BLD_<yourproject>.prg to build your EXE file
    Use BLD_<yourproject>.PRG which was created by the New Project Wizard to compile and build your servers. It will do away with DCOMCNFG except for the first time configuration of the default access settings if required.

  • Don't go overboard with COM instances
    While you can run multiple instances of servers the optimal configuration of performance and response time seems to be two instances per CPU. If you have longer requests more sessions can help responsiveness of your site, but remember overall performance won't improve with more instances as these instances compete for the same CPU resources.

    A recommended starting point for instances is 2 instances per processor. If you have light load operations

  • Fixing multiple DCOM entries for the same server
    If you were not careful and end up with multiple DCOMCNFG entries for the same server you may have to do one of two things: Clean up the registry or create a new ProgId/ClassId for your server. For the former take a look here.

    If your DCOMCNFG settings get totally screwed up due multiple ProgId entries, you have two things you can do: Create a new project with a new project and class name. Or you can clean up the registry. To clean up the registry search for the ClassName in the registry and wipe out all trees that contain this name. For badly corrupted servers this can be as much as 50 entries that need to be cleaned out. When you wipe out subtrees you want to wipe out the subtree for the AppId and ClassId entries. Be very careful - know what you're doing, and if you don't ask for help.