Databases - Delphi ISAPI Web Server

The purpose of a Web Server is to generate a web page (html) that is displayed in a regular web browser.

A CGI Web Server is an *.exe file - ISAPI and NSAPI Web Servers are *.dll files.

*.dll Web Servers are better (faster and more efficient) for high volume sites, but they are very difficult to debug because the main Web Server (IIS, Netscape, Apache, and the like) must be shut down each time a new *.dll is compiled. As a result, it is always easier to create a CGI server first and convert it to an *.dll latter. (Only the project (*.dpr) file is different.)

WebServer_CGI.html shows how to create a CGI server. The "only" difference between a CGI program and an ISAPI program is the *.dpr file. Other differences are discussed below.

Converting a CGI Application

The basic procedure is to create a new ISAPI application, delete the default unit (*.pas file), and reuse the same code used for your CGI program. It is important to save the project (*.dpr file) before adding an existing module - if this is not done, then the path to the *.pas file is saved in the *.dpr file.

Setting the output directory just makes testing a little easier.

Example *.dpr files

CGI *.drp file ISAPI *.drp file Notice that these are identical except for Borland provides an example dpr file that contains conditional code for both server types - CGI & ISAPI. The output is controlled by commenting out a control statement.

Running your program under IIS

To run your code under IIS, you must place it in a directory that has permission to execute programs.

Typically, your files are stored as

and accessed as Notice: You can not compile a new copy of your file if the current copy is open (running).


This is the problem with dll's - they are very difficult to test.

Basically, the web server (IIS in my case) opens the *.dll file and never closes it. Microsoft does not provide any mechanism for a dll to close itself - it must be closed by the program that opened it. Microsoft also does not provide a way for IIS to close individual *.dll's. As a result, you must shut down and restart IIS before your changes will take effect. (This is why I originally suggested developing your application as a CGI file and testing this first before you use it as a dll.)

The other problem is that the Delphi IDE debugger can not be used unless Delphi runs the code. Thus, when IIS runs your code, you will need to use other methods to debug it.

Other Differences

On the surface, the only difference between CGI and ISAPI files is the *.dpr file - but there are other differences.

Filename and Command Line

I like my programs to use *.ini files to get various configuration paramters - such as the name of the database server. Typically, the test database server has a different name than the production server. Generally, I place the *.ini file in the same directory as the executable.

To get the directory name in either an *.exe or an *.dll, use

It took several hours to find how to determine the directory that the *.dll file is in.

is available only for applications that have a form - exename is implemented via in forms.pas, and ParamStr is defined in the system unit.

This is my test code

In a CGI file, it produces In an ISAPI dll file, it produces For dll's, CmdLine returns null.

I found the solution via Filename of the application (exe/dll) - it provides an example showing how to use the Windows GetModuleFileName command.


Use IsLibrary to determine if the program is a dll.


It appears that Timers don't work ... they are never called.

I have an ISAPI server that creates temporary jpeg's. Once every 10 minutes, I want the dll to check and erase any jpeg over 1 hour old. The logical choice was a TTimer - except that it was never called.

Instead, I added the cleanup code to the method that actually creates the jpeg files. Unfortunately, on a busy site, this code could run a thousand times a second instead of once every 10 minutes. I consider this to be a poor compromise.

Originally, I named all the jpegs the same - the application simply kept over writing the one file. However, some browsers cache the images and never show the correct data. I tried setting every html parameter I could find to force the browsers to dump the cache an load the current image. Since that never worked, my solution was to give each image a unique name and then to delete the old ones to save memory. Now I need to erase lots of temporary files.

Additional LInks

Debugging DLL on WinXP lists several ways to debug an ISAPI dll.

Debugging IIS5 ISAPI Applications with VC++ explains how to configure IIS and windows to allow debugging.

Author: Robert Clemenzi -
URL: http:// / user / clemenzi / technical / Databases / Delphi / WebServers / WebServer_ISAPI.html