Working with COM Components with
IIS 4.0 and Active Server Pages
by Rick Strahl, West Wind Technologies
http://www.west-wind.com/
last updated: December 27, 1997
Internet Information Server 4.0 has changed the rules on how COM objects are
instantiated and a few changes have to be made from the procedures you might have used
under IIS 3.0 when building and debugging your COM objects loaded from Active Server
Pages.
Review of Active Server Components for use in VFP
Active Server Pages makes it possible to instantiate COM/Automation objects off an
Active Server Page by using the Server.CreateObject("ProgId") syntax. This
mechanism allows accessing any external components created by applications such as Visual
FoxPro, Visual Basic and low level tools such as Visual C++ or Delphi. These components
can be standard COM components or implement a few special methods to become Active Server
Components. Active Server Components can access the ASP internal objects by receiving a
reference to an Object Context that makes available the intrisic objects - Request,
Response, Server, Application and Session.
COM Object Servers can be built as DLLs or EXE servers. ASP encourages use of InProcess
DLL servers, but you can run EXE servers by setting a special registry key in IIS 3.0 (HKEY_LOCAL_MACHINE\SYSTEM\
CurrentControlSet\Services\W3SVC\ASP\ Parameters\ASPAllowOutofProcCmpnts)
or a MetaBase entry (ASPAllowOutOfProcComponents set on
either the Root or specific virtual directory see ). There are serious limitations
in regards to scalability with Visual FoxPro Automation servers, but any components built
as InProcess objects built to the Apartment Model thread model (or 'Both' Apartment or
Free threaded) works well and can scale with multiple simultaneous instances. VFP supports
neither of these models and allows only single threaded access to Components. This
limitation will be addressed in Visual FoxPro 6.0 by Microsoft.
To implement an Active Server Component the component should have a OnStartPage method
at least and optionally an OnEndPage method. OnStartPage passes an ObjectContext
parameter that exposes the other objects. Here's a simple example of a Visual FoxPro
implementation of the method:
DEFINE CLASS cASPComponent AS CUSTOM
oObjectContext = .NULL.
FUNCTION OnStartPage
LPARAMETER loObjectContext
IF TYPE("loObjectContext") = "O"
THIS.oObjectContext = loObjectContext
ENDIF
RETURN
ENDDEFINE
It's now possible to get a reference to any of the ASP built in objects in a method
like this:
loRequest = THIS.oObjectContext.Request
lcBrowser = loRequest.ServerVariables("HTTP_USER_AGENT").item()
lcFormVar=loRequest.Form("FormVarName").Item()
Although you can implement the OnStartPage() and OnEndPage() methods they're not
required. Even if you need access to various objects of ASP you may not need these
methods. You can also directly pass these objects to your server methods as parameters.
The new Security Model in IIS 4.0
IIS 3.0 had a simple security model that used the IUSR_ account of the local machine to
impersonate any Automation object created by ASP. This means that Automation servers are
very limited as the IUSR_ account has very few rights. While you can change permissions on
this account it's not recommended since all Internet users come in under this account and
too many rights can be a serious security risk to your Web site. Out Of Process Automation
servers have the option of overriding security settings by using DCOMCnfg to configure the
Automation server to a specific user impersonation.
IIS 4.0 introduces a new security model where Applications run under several accounts
and services that are active simultaneously. The InetInfo Service now consists of the
IISAdmin service and the other specific functional services such as Web, FTP and Gopher
servers. In order to totally shut down IIS you need to kill both the Web Server (and FTP
server if it's running as well) and the IISAdmin service.
In addition the ISAPI subsystem (ASP is an ISAPI extension and runs under the ISAPI
subsystem) runs inside of Transaction Server. It is now possible to isolate individual
applications to run in their own address space inside of a separate Transaction Server
session. This allows the session to be shut down independently of the Web server and any
badly behaved code will only crash the MTS session (which will retry to restart itself 5
times) and not the entire Web server.
This reliance on Transaction Server brings with it advantages and changes in the way
you have to configure your servers.
DLL In Process Servers
- Active Server loads InProcess (DLL) COM components and keeps them in memory, always.
This means if you're building and debugging your component you cannot rebuild it as the
component is in use.
- To work around this set up your ASP application in a virtual directory and mark it to
run 'Separate Memory Space' in the IIS Admin Console.
When you do, DLL servers can now be unloaded by right clicking on 'Properties' and then
clicking on the Unload button on the Virtual Directory|Application Settings tab.
- DLL components always run under the IUSR_ account and cannot not be configured
externally to run under another account. You can however use the API to use the various
Impersonation API calls to change the user account inside of your component code (Note
this is very difficult to do in native VFP and you'll likely have to create a DLL or
component in C to do this efficiently).
EXE Out Of Process Servers
- EXE Out Of process Servers must have the ASPAllowOutOfProcComponents MetaBase Key set in
order to work. See IISAdmin.htm for details on how to
accomplish this.
- Unlike IIS 3.0 EXE servers need to be configured with DCOMCnfg. This utility sets the
Impersonation of an Automation Server. You need to set the Impersonation to an account
that has rights to launch the server. Preferably use the Interactive User (if the machine
is logged on) or else use an Admin account (it's safe since it's a server component that's
not accessed by users directly).
Debugging tips for Automation Servers
You can use VisualFoxPro.Applicaction and its EVAL() method to call a Program
file. Use the program file to instantiate your class and pass parameters along to the
appropriate methods. This way you can 'interactively' debug servers. Unfortunately, you
can't pass objects or long strings that way but for simple parms it should work.
For example you can do oServer.Eval("ASPDebug('Parm1','Parm2')") from within
VBScript. You then create a program file called ASPDebug somewhere in your VFP default
path. it might look like this:
PROCEDURE ASPDebug
LPARAMETER lcParm1, lcParm2
SET STEP ON
oServer = CREATE("MyClass")
oServer.MyMethod(lcParm1, lcParm2)
lvResult = oServer.SomePropertyOfServer
RETURN lvResult
This routine serves as a simple wrapper that calls your component as a straight VFP
class. The key here is that you're instantiating the Visual FoxPro development environment
and therefore can debug the code by setting a breakpoint.
|