Web Connection is a complete Web application framework for developing and delivering scalable e-business solutions with Visual FoxPro. It is a proven development platform for integrating browser, server and database technologies into Web applications for Visual Studio and especially Visual FoxPro developers.
Make sure you read the following important topics:
This documentation is large, yes. Don't let it scare you off though, most of the information is here to help you with specific functionality, but for getting started you only need to know a few things.
Don't know where to start? Here are links to get you on your way:
Can't find it, or you're stuck? Try these support links:
*** Action required: Check and ensure your Web Service doesn't require explict type returns. If it does add: this.oSOAP.lIncludeTypes = .t. to Init() of the service to get old behavior
*** Action required: If you set the lUseErrorMethodErrorHandling flag in your code you will have to adjust this flag and move the code to your server's OnInit method or as a property override setting in the class definition of your wwServer subclass.
*** ACTION REQUIRED:
To take advantage of this feature make sure that ZLib1.dll gets deployed on the server with your application.
*** ACTION REQUIRED:
Make sure you update both wwIPStuff.dll and wwIPStuff.vcx in your applications. There was a change in the DLL to provide this feature. The new code will not run with the old DLL, but old code will work with the new DLL.
Behavior change: The new behavior is the default and it might cause some problems with some existing scripts especially if you manipulated headers. wwVFPScript is no longer loaded by default. To switch back to the old behavior set the WWC_SCRIPT_PROCESS setting to wwVfpScript and WWC_LOAD_WWVFPSCRIPT .T. in wconnect.h/wconnect_override.h.
wwWebAjax Control added
There's new AJAX control that is part of the Web Control Framework that provides very easy AJAX integration into existing applications. The control supports hover window popups from URL content, very easy URL callback support and a simplified Page Method Callback Mechanism that makes it super easy to callback on the current server page and return values using a simple RPC style interface.
wwUtils.File2Var reads and writes in shared mode
File2Var now always reads in shared mode meaning that files can be accessed at the same time. This might improve performance a little with template reads and the like. For writing there's an optional flag that allows shared writes as well although you should be very careful with this option and only use it in special situations. Unlike STRTOFILE and FILETOSTR(), File2Var doesn't cause a FoxPro error but instead returns a blank or .T. and .F. respectively.
wwRequest::lUtf8Encoding
Added a flag that allows retrieving all request data in UTF8 format. When set both QueryString and Form variable retrievals are UTF-8 decoded into the current character set (STRCONV(,11)). This is required for any client page that posts data in UTF 8 format - such as any request data encoded using JavaScript encode or encdeUriComponent functions.
This change greatly simplifies COM configuration and allows Web Connection in most cases to run in COM mode without any additional configuration beyond COM registration with /regserver. The change also mimizes and simplifies the security impact and gives Administrators control over the security environment that the Web Connection application runs under.
The new operation is implemented by default but a new Impersonation switch in wc.ini allows switching back to the old style of Impersonation operation.
For current pricing for both developer and runtime licenses please check our product pricing page.
Runtime licenses may also be applied against additional developers on a team with one license per developer required.
A runtime license allows distribution of a compiled Web Connection application and distribution of any of the binary files included with Web Connection. No portions of the Web Connection framework may be re-distributed as source code without a full developer license. Runtime applications can make use of any of the framework classes supplied by the Web Connection framework including the HTML rendering classes and support tools as long as distributed in compiled form (APP/EXE).
Applications built with a distribution license must add significant value and cannot be in competition with the Web Connection development product. The Message Board and Offline Reader applications of Web Connection are excluded from any runtime agreement and may not be re-distributed in volume. A separate license agreement and pricing applies to redistribution of the message board application.
You may modify the source code and visual appearance of the Visual FoxPro Web Connection framework. Regardless of any changes made to the framework itself, it remains copyright of West Wind Technologies. Modification of any non Visual FoxPro binary files is not allowed.
The topics in this tree describe key changes in the framework that will affect existing applications.
The main concern is that unchecked nested tags containing user input could easily execute code in your pages in unexpected situations which opens up a huge security hole. For this reason recursion is off by default, and we don't make it real easy to turn it back on.
With recursion on, imagine a user entering this into a textbox:
<%= Version() %>
If your template now echos that value with:
<%= lcInputValue %>
and recursion is on the page will display the FoxPro version number! At this point, effectively the user has executed code in YOUR FoxPro application. Version() is one of the milder problems of what can execute...
So for this reason we've turned off recursive expressions. If you really need recursive expressions, you can use:
<%= MergeText(lcValue) %>
which now explictly recurses the result value.
The wwEval object also contains a lAllowEvalRecursion flag that is off by default. If you have pages that you know explicitly require recursive expressions you can forego ExpandTemplate and instead use this equivalent code:
loEval = CREATE("wwEval") loEval.lAllowEvalRecursion = .T. lcResult = loEval.MergeText( FILE2VAR( Request.GetPhysicalPath() ) ) Response.Write(lcResult)
The DEBUGMODE flag is replaced primarily by the Server.lDebugMode flag now. This flag is now dynamic and can be changed in your appMain.ini file or even dynamically at runtime on the Server Status form.
Action Item:
You should check all of your code and find any DEBUGMODE usage. Especially check your custom wwProcess subclasses and make sure that there aren't any DEBUGMODE flags. If they wrap Error Methods see the next section on how to change your code.
FUNCTION OnError(loException as Exception) * ... your custom error code here ENDFUNC
This method serves exactly the same functionality as the old Error method did, but as you can see it doesn't receive three parameters, but rather a FoxPro Exception object. Errors are caught in a TRY/CATCH as part of the Process class' Process() method and wrapped around the RouteRequest() method. This captures any error in your code and fires the OnError() method on your wwProcess subclass.
Keep in mind that overriding OnError is optional. The most common scenario is overriding how the error message is displayed and you can override that instead by overriding the ErrorMsg() function.
But if you need to explicitly manage your errors here's the default OnError implementation that you can emulate:
FUNCTION OnError(loException as Exception) *** Shut down this request with an error page - SAFE MESSAGE (doesn't rely on any objects) THIS.ErrorMsg("Application Error",; "An application error occurred while processing the current page. We apologize for the inconvenience. " + ; "The error has been logged and forwarded to the site administrator and we are working on fixing this problem as soon as we can.<p>" + ; "<p align='center'><table cellpadding='5' border='0' background='whitesmoke' width='550' " +; "style='font-size:10pt;border-collapse:collapse;border-width:2px;border-style:solid;border-color:navy'>" + CRLF +; "<tr><td colspan='2' class='gridheader' align='left' style='font-weight:bold;color:cornsilk;background:navy'>Error Information:</th></tr>" + CRLF +; "<tr><td align='right' width='150'>Error Message:</td><td>"+ loException.Message + "</td></tr>" + CRLF +; "<tr><td align='right'>Error Number:</td><td> " + TRANSFORM(loException.ErrorNo) + "</td></tr>" + CRLF +; "<tr><td align='right'>Running Method:</td><td> " + loException.Procedure + "</td></tr>"+CRLF+; "<tr><td align='right'>Current Code:</td><td> "+ loException.LineContents + "</td></tr>"+CRLF+; "<tr><td align='right'>Current Code Line:</td><td> " + TRANSFORM( loException.LineNo) + "</td></tr>"+ crlf +; "<tr><td align='right'>Exception Handled by:</td><td>" + THIS.CLASS + ".OnError()</td></tr></table></p>") *** Log the Request IF TYPE("THIS.oServer")="O" AND !ISNULL(THIS.oServer) this.LogError(loException) ENDIF *** We've completely handled the error! RETURN .T. ENDFUNC
The typical flow of a request now is:
This behavior still exists, but the recommended hook point now is OnProcessInit().
Action Item: Rename Process() to OnProcessInit
In most cases you can simply rename your Process() method if you even have one to OnProcessInit() and you should be good to go. The only rare exception is if you need to create PRIVATE variables visible further down the call stack. For more info see the OnProcessInit() topic.
Action Item: Add PRIVATE defines at the top of the Process PRG file
If you use the new Wizards, Web Connection automatically generates a set of PRIVATE vars for the 'known' server objects like Request, Response, Server etc. at the top of the PRG file so that they are always visible. This makes it possible to make assignments to these classes at any time without worrying where you are in the FoxPro call stack.
LPARAMETER loServer LOCAL loProcess PRIVATE Request, Response, Server, Session, Process STORE .null. TO Request, Response, Server, Session, Process
Tip: Can't use the wwPageResponse class? Try wwPageResponse40
The wwPageResponse class removes many 'utility' methods of the wwResponse class. If you have legacy response method calls that don't work with the wwPageResponse class, there's another subclass of the class called wwPageResponse40 that adds back the various dropped methods like all of the Form???() methods, Send/SendLn and a few other methods that had been dropped.
Web Connection 5.0 works with the old Response classes by default, so you don't have to change anything to get your code to run. However if you want to use the new object you will have to make a few adjustments to your existing code.
Action Item: Enable the wwPageResponse class
In order to use the new wwPageResponse class you have to set a property in your wwProcess subclass definition.************************************************************* DEFINE CLASS wwStore AS WWC_PROCESS ************************************************************* cResponseClass = [WWC_PAGERESPONSE] *** If you need to use the 4.0 compatibility class * cResponseClass = "wwPageResponse40" ... ENDDEFINE
The wwPageResponse class mixes wwHttpHeader and wwResponse functionality so anything that used to require separate headers can now in most cases use the wwResponse object directly. For example:
Response.AddCookie("TestCookie","MyValue","/wwstore") Response.Headers.Add("Expiration","-1") Response.AddForceReload()
The old way still works as well so you can still construct a wwHttpHeader object and pass it to ContentTypeHeader(), but this is not recommended because that mechanism will output the header immediately.
Action Item: Remove wwHttpHeader code and replace with Response methods
To optimize your code remove any wwHttpHeader related code and use the Response methods directly.
Make sure you test your code. If you should run into problems with headers they will most likely be related to duplicate headers. In those cases make sure that you are not explicitly writing out headers in your application code. Always try to use the wwPageResponse object directly.
If you're using SQL Server log and session data you will need delete the Log and Session tables and then run the Console SQL Wizard to recreate them or manually update the tables.
wwRequestLog Changes
The wwRequestLog has been updated to hold a unique Request Id that is passed from the ISAPI extension.
CREATE TABLE (THIS.cLogFile) FREE ; ( ; TIME T ,; REQID C(20),; Script c(50) ,; QueryStr M ,; REMOTEADDR C(16) ,; Duration N (5,2),; MemUsed C (8) ,; ERROR L ,; REQDATA M,; Browser M,; Respone M )
For SQL Server:
CREATE TABLE [dbo].[wwrequestlog] ( [time] [datetime] NOT NULL , [reqid] [varchar] (20) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [script] [varchar] (50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [querystr] [varchar] (254) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [duration] [numeric](7, 3) NOT NULL , [memused] [char] (8) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [error] [bit] NOT NULL , [reqdata] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [browser] [varchar] (156) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
wwSession Updates
The wwSession class has changed the way the Session table is created by widening the SessionID to 14 characters. The widening is to ensure unique session ids that create SYS(2015) plus the current ThreadID.
If you use FoxPro Table Session (wwSession) then you can simply delete your wwSession table. Web Connection will automatically recreate the file as needed. The update structure is:
CREATE TABLE ( THIS.cDataPath+THIS.cTableName ) FREE; (SESSIONID C (14),; USERID C (15),; FIRSTON T ,; LASTON T ,; VARS M ,; BROWSER M ,; IP M ,; HITS I )
If you forget to update your FoxPro table the code will still work but the new ThreadID is stripped. This is not really an issue - you get essentially the old behavior. This change really only affects high volume applications where many instances are running simultaneously.
For SQL Server you will need to modify the database and change the
CREATE TABLE [dbo].[wwsession] ( [SessionID] [char] (14) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [UserId] [char] (15) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [firston] [datetime] NOT NULL , [laston] [datetime] NOT NULL , [vars] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [browser] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL , [ip] [text] COLLATE SQL_Latin1_General_CP1_CI_AS NULL , [hits] [int] NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] GO
If you forget to update the SQL Session table you will get errors when trying to write a new session record.
West Wind Most Valuable Professionals
We're acknowledging the support many of the people in our community have given back to others on the message board and around shows and other events. We here at West Wind Technologies and the community at large thanks these individuals by awarding MVP awards. To find out more visit the MVP site.
Randy Pearson
Randy Pearson of Cycla Corporation has been an extremely active member in the Web Connection user community to the point that many people visiting the message board think he's a West Wind Employee, which he is not. His valuable contributions and thoughtful comments and suggestions can also be found in many aspects of Web Connection and had an impact on many of the features found in the product. Finally, Randy was in charge of the Migration topics found in this help file along with with the Migration Tool utility to move 2.x projects to 3.x. Randy is also co-author of the WebRad Web Connection book.
Lauren Clarke
Lauren has become one of the top resources on the West Wind Message Board and has been a huge help in testing various new developments in Web Connection. He's also been instrumental in a number of ideas and tossing around brainstorming ideas for new features in the product.
Markus Egger
Markus (EPS Software) and I have been business and development partners for some years now and Markus although not directly involved in this product has always been a great help in bouncing ideas and concepts off of. Many of these have found their way into Web Connection.
James Murez
For all of his help related to pushing Web Connection harder as a product and improving visibility both for WWWC as well as Visual FoxPro in general. He's also been very actively testing several not so often used components of Web Connection and provides tons of feedback both on the documentation as well as on bugs/inconsistencies.
Erik Moore
Erik has worked on some technologies that have been silently integrated into Web Connection and he's had valuable feedback and discussions on several topics ranging from XML, SQL and ADO to the WinInet functionality in wwIPStuff.
Ken Levy
Ken's been big help in providing info on XML and a link to Microsoft for bugs and odd behaviors. Even though he cut his hair and doesn't work in the Fox team anymore, he's still one of us. Ken's been invaluable in helping isolate a number of bugs in the DHTML and XML object models that have been fixed since.
Microsoft Visual FoxPro Team
For the obvious: Providing us with a tool that is so powerful and lets us do things so easily that it simply boggles the mind that you can't do many things in other more visible Web products. I want to specifically thank Calvin Hsia for his help on many COM related issues on the road to providing the scalability in Web Connection. Also, Randy Brown for his support and help with various WinDNA related issues in VFP.
The frequent Message Board Crew
Yeah, that's all of you who frequent the message board and help out others or ask pointed questions about features and (gasp) bugs. Without this feedback this product would not evolve as much as it does.
I thank all of you for your help and support of making this product such a success in the FoxPro market!
+++ Rick ---
Rick Strahl
West Wind Technologies
This is not an issue with the full version as source code is available and VFP can properly
load the classes from the source code when run.
If you see this error there are two ways to deal with it:
and then re-run the demo or menu option.CLEAR ALL CLOSE ALL SET CLASSLIB TO
It's good practice to assign the following to a Macro key in VFP:
CANCEL CLEAR ALL CLOSE ALL RELEASE ALL CLEAR PROGRAM CLEAR SET CLASSLIB TO SET PROCEDURE TO
However, you can stil run any Web Connection application simply by executing the main PRG file (ie. DO webDemoMain.prg).
In the full version you can swap the flag to .F. which makes Web Connection handle errors and display an error page and send notification emails etc. but in the shareware version the behavior is fixed to break at the error.
If you've modified any of the sample files be aware that the sample files will be overwritten in the installation - hopefully you will have created new projects in their own separate files rather than modifying the existing files. If not, make sure you back up these files first before installing the update.
After you've installed the new files over the shareware installation, make sure you:
You can do the following from the VFP Command Window in the Web Connection startup directory:
RELEASE ALL DELETE WCONNECT.APP DELETE FILE classes\*.fxp DELETE FILE *.fxp COMPILE classes\*.prg COMPILE CLASS CLASSES\*.vcx
These are the only software requirements that you have to have. Web Connection is developed and tested with IIS Web Servers and that's what works best. However there's also limited support for Apache, but the installation and configuration is not as automated as with IIS. Currently there are also issues with Apache 2.2 or later due to recent changes in the Apache Module architecture. Apache 2.1 and earlier are fully supported. For Apache 2.2 Web Connection has to run in CGI mode.
The following optional components are recommended:
Visual Studio 2008/2005 or Visual Web Developer
If you plan on using the new Web Connection 5.0 Web Control Framework you will want to use a version of IIS to layout and design the Web Control Pages in Visual Studio. Web Connection integrates with Visual Studio and provides FoxPro source code editing and browser previewing through the IDE. VIsual Web Developer is a free tool from Microsoft and it's sufficient for use with Web Connection. VS is not required however - Web Connection has no dependencies on Visual Studio or .NET at runtime and the Web Control Framework is based on pure text documents. Visual Studio is merely used to provide a rich design experience for the Web Controls. Any editor including NotePad or the VIsual FoxPro editor works.
The following components are useful but completely optional when running Web Connection:
Office Web Components for graphing
The Office Web Components are used on some of the graph demos and internally to generate graphics for the logs and a few other places. These components require an Office license (2000 or XP). It's recommended you download the latest version from the link below even if you have Office XP as the ClassIds for these components have changed.
http://office.microsoft.com/downloads/2002/owc10.aspx?HelpLCID=%HelpLang%1033
Web Connection Supports the following Web Servers:
The product is designed primarily on Microsoft Internet Information Server (IIS), which provides best performance, stability and the full range of features. It also works well with Apache 2.0 and 2.2 and can be used with any any other ISAPI compatible server on Windows. We do recommend IIS especially IIS 6 or 7 as it provides the most stable and compatible platform for Web Connection on which Web Connection is developed and tested.
If you plan on working with the Web Control Framework you'll want to use Visual Studio 2008 or the free Visual Web Developer 2008 (Visual Studio 2005 and VWD 2005 are also supported). Web Control Framework pages are plain text, but in order to get the full design experience a ASP.NET 2.0 compatible environment should be used. Click here for more info on whether you need Visual Studio.
Otherwise plain HTML editing tools like FrontPage and Dreamweaver can also be used for editing standard templates or even Web Control Framework templates (although you won't get full designer support for the controls). Of course you can edit any HTML templates including script and Web Control Framework templates with any text editor like Notepad or even the Visual FoxPro text editor.
For development we recommend the max amount of memory you can afford as it will make your dev environment work more smoothly. With memory under $50 a gigabyte, it's easy to justify running with 4 gigabytes of memory or more. Web development is very memory intensive especially if you use Visual Studio or Visual Web Developer. Also a fast machine won't hurt for development as you spend a lot of time flipping back and forth between different applications (VFP, Web Browser, HTML Development Tool etc.).
The latter option tends to be the cheapest but unfortunately it's not likely that you will be able to use it for your Web Connection applications as a WWWC application requires binary executables which are usually not allowed by low end Web hosting services. However, there are special providers that specialize in hosting binary based application services and you may be able to talk to your ISP to get them to host you in this fashion.
Co-location lets you have your own machine or one provided by the ISP at their facility. The big advantage here is that you have full control over the server and can configure it as you choose. This usually includes the ability to add custom user accounts, set the security permissions for the server, add remote access services for pcAnyWhere or the like. It also makes sure that your application is the only one running on the server so that there's no interference or problems from these potentially dangerous applications running on the server at the same time. Co-location tends to be more pricey but for the piece of mind and control can save you lots of headaches. Pricing varies, but typically runs $200 a month and up.
Finally your company may already have an internal Internet connection and you can hook your server application into that network. In this situation you probably have to deal with your network administrator and any of the security policies configured for the company network. If your application is completely internal to your company (an Intranet) then a public Internet connection is not required. If your application is used both internally and externally (an Extranet) you will still need with the security issues of an open Internet connection through your IT staff.
For a list of providers that are Web Connection and Visual FoxPro friendly and provide related services, see http://www.west-wind.com/webconnection/webhosting.asp.
You can use Word to print the document into hard-copy. If you don't own Word 97 or Word 2000 or Word XP you can download the Word viewer from:
Note: The Word documentation may not be the very latest version as we only periodically update the Word docs. The Word file is also very large and you'll likely want to print only selected sections.
http://www.west-wind.com/wwthreads/
Before you post:
Please, double check your code before posting to make sure you didn't overlook something obvious. When you post make sure you provide as much information as possible. Most importantly provide any error information that might be available for the Web Connection classes and Visual FoxPro. Most Web Connection classes have an lError flag and a cErrorMsg property which you can check for failure information. All of this will ensure we can answer your question more efficiently and get you up and running as quickly as possible
Additional Support:
If you require additional personalized support, you can contact West Wind Technologies for paid support via Email or Phone. We also provide customized on-site training and mentoring services. You can contact us for any of these services at:
West Wind Technologies
32 Kaiea Place
Paia, HI 96779
USA
Email: support@west-wind.com
Phone: (503) 914-6335
Fax: (815)572-0619
Please be aware that support is charged at regular consulting rates of $150/hr in half hour increments.
The message board provides the following features:
To run the Message Reader click on the West Wind Message Reader option from the Web Connection menu pad in Visual FoxPro or click on the shortcut in your Task Bar's Web Connection group.
The offline reader allows you to compose and read messages in the rich environment of a GUI application and provides support for creation of rich messages using standard editing features. As the name implies you can read and create messages offline and post them, get more messages when you reconnect. This is ideal for people while travelling or for those that have slow dial up connections. This environment is also much nicer to use than the Web application, so give it a shot.
The bug report form asks you create a detailed error report to provide a reproducable scenario.
Please use this form only for problems that are reproducible or are outright bugs. If you're not sure how a feature or command works post a message on the message board. This mechanism is meant to be used as a basic bug tracking mechanism on the message board to allow tracing bugs from submission through resolution via message threads.
http://www.west-wind.com/wwDevRegistry/
Web Connection provides a powerful modular framework that interfaces FoxPro with the Web Server. The core engine provides all the interfacing and server infrastructure with various modules and handlers plugging into the architecture. You can choose from building applications that use pure code to generate output, to using high level modules like the powerful Web Control Framework that provides a rich object oriented control and event based model to build applications more efficiently using a more familiar and productive desktop metaphor.
Web Connection provides you with lots of choices for generating output from your application. At the lowest level you can do everything in code - respond to requests, picking up request data with pure code and running your own FoxPro code to generate HTML output. Other mechanisms provide more highlevel generation tools. The base script support allows you to use external templates with a textmerge like mechanism to externalize HTML generation. You can generate output from FoxPro reports to PDF files and use many high level functions to generate HTML from data quickly.
Finally there's the powerful Web Control Framework which manages many aspects of Web Page display. It automatically manages page state, and re-assigns control content on postbacks, allows persisting data across requests and can generate HTML from easy to use controls that you can programmatically access in your code. You simply set the text property of a textbox, vs. generating HTML for the entire textbox for example, and communicate with the textbox's properties to set things like color alignment, fonts etc. The Web Framework in conjunction with Visual Studio or the free Visual Web Developer allows you use a visual drag and drop design surface and easy to use property editors to visually design your layouts and set up control layouts. This is the recommended mechanism for building Form Centric HTML Web applications with Web Connection 5.0.
The Visual FoxPro framework consists of classes that manage communication with the Web connector ISAPI extension. They handle server management and administration, retrieving server and browser form variables from the server making them easily available to your code and providing a powerful set HTML classes and support tools that make short work of interactively building the HTML required to display your application on the Web. Web Connection provides access to all advanced HTTP based features including displaying HTML script pages containing FoxPro code and expressions from disk. Many advanced features like HTTP Authentication, HTTP Cookies, Sessions, custom HTTP headers, request logging, remote administration and configuration and server load balancing are built into the product and easily accessed through the framework.
And you can use rich design tools with Web Connection, so you can use FrontPage or Dreamweaver and the like to design your page templates, or if you're using the Web Control Framework using Visual Studio or Visual Web Developer to design your pages graphically in an interactive WYSIWYG environment.
You can use existing business object frameworks with Web Connection. There are countless applications out there that use Mere Mortals, FoxExpress, Visual MaxFrame and others with Web Connection. And Web Connection itself also includes its own light weight business object framework that you can optionally use. While a Business Object Framework of some sort is recommended you don't have to use it of course - you can use FoxPro code and data access directly just as well.
Web Connection can also built Fat Client applications let you use Visual FoxPro desktop applications communicating with a Web Connection (or other) Web Server application. Web Connection includes a rich set of client tools that can provide connectivity over HTTP using plain XML or the SOAP protocol for Web Services.
With Web Connection you can run SQL queries over the Web and create and call Web Services. You can create custom XML services or use more standard Web Services. Web Connection provides the client side HTTP tools as well as high level XML conversion tools that make XML integration a snap. The Web isn't all about HTML and these data messaging features let you build powerful distributed applications that aren't limited by HTML output. Several examples that demonstrate rich client applications are also provided in the box.
Some examples include a WebLog example, the Message Board application and a PhotoAlbum application to name a few.
Web Connection has been field tested on a number of high volume sites and even back in 1996 there were sites running in excess of 2 million hits a day. Imagine what you can do on today's hardware.
So read on and get ready to get Webbified! It's never been easier to build Visual FoxPro Web Applications!
Web applications are server based and respond to requests made from a Web page. Every action that occurs on a Web page generally fires back to the Web Server. In that sense Web applications are not truly event driven but follow a more rigid transaction based Request and Response model. Web Applications also are stateless and that imposes additional considerations. The short of it is that Web applications by nature are VERY different from Desktop applications.
The new Web Control Framework provides a programming model that is conceptually similar to Desktop Form development and is the recommended approach for first time developers as it provides a familiar control and event based metaphor for building Web applications. But even though the model is similar, understand that you are still bound by the limitations of HTML/HTTP based interfaces, so don't expect to be able to EXACTLY duplicate desktop application interfaces via HTML. This is neither always possible nor desirable as HTML interfaces often have different design targets.
The core feature that Web Connection provides is the ability to continue to use FoxPro code to build your Web applications. You can write code in the tool you are familiar with and you can likely reuse any non-User interface code in your Web application.
Another option for existing standalone applications is to build a distributed application that use the Web as a data transfer mechanism. If you go this route your UI code can potentially be reused using data pulled down from the server using tools in the wwIPStuff library. See the Online Distributed Application Demo for an idea of what you can do.
If you're new to the Web take a deep breath and read on - there's lots of info in this document that will clarify the way the Web works. Web Connection makes it easy to leverage your FoxPro skills. Once you understand the basic flow of information over the Web things will fall into place and allow you to be productive very quickly. You can crank out quality high performance applications without having to learn all of the Web technology up front and you'll learn about Web technology as you use Web Connection to build applications.
This topic is designed to summarize the things that you should most definitely look at. It gives you an idea on where to start, what to try to get going and where to look for more information.
Use the Help File! It's got tons of information, and if you get stuck the answer is likely in here. It's keyworded and searchable in addition to the Content view, so take advantage of this very rich resource.
Most of the examples on the demo pages have links to show you the source code required to create that request by clicking on the [Show Code] link on the bottom of the page. At this time you can also start poking around in the code, making a few adjustments, maybe creating a new method and stepping through the code to get an idea what's involved in writing code for Web functionality.
There are two sets of samples: Core samples and Web Connection 5.0 samples, which sit on a separate page. To get started it may help to look at a few of the core samples first and see how Web Connection works in 'raw' code mode. Once you get the basic idea of how the Request and Response objects and the wwProcess class work, then you can take a look at the Web Control Framework (WCF) samples, which is the focus of Web Connection going forward. The WCF is conceptually a little more complex at first because there are many user controls to get familiar with, but it provides a much more interactive and flexible Web development approach to building Web applications. Both 'core' functionality and the new WCF features can co-exist in a single application.
This step is optional, but if you want to get the most out of Web Connection this topic tree will be well worth the time to read easpecially as you get more experienced with Web Connection.
The new project will set up a new VFP application for you that you can start to write your own requests with. Now it's time to write access your business logic from within these Web requests and create some output to display back in the browser. As you start writing code you likely run into a few situations where you don't know how to do something. I suggest you go back to the demos and see if you can find something there that demonstrates what you're trying to do. Again, the message board is a great resource to post questions to if you get stuck or even if you want to bounce some ideas of other developers who have been down the path.
The User Guide provides you with general discussion while the Class Reference (Framework Classes, Framework Support Classes, Utility Classes) provides detailed information on the actual classes in the framework. The class reference is laid out to provide an overview in the class header topic with examples and things to look out for with the actual class detail following class reference format showing the actual mechanics.
You can also resort to the Management Console and the Server Configuration Wizard to help you with configuring your Web server with the appropriate virtual directories and script maps as well as copying and registering the Web Connection components for your application.
You can also work with the Visual Studio Web Server which makes it possible to work without a fully installed Web Server.
Microsoft Internet Information Server (IIS)
Most recent versions of Windows come with a version of IIS that can be used on your local machine.
IIS on Windows is installed as a Windows component and can be enabled through the Programs and Feature Control Panel applet | Windows Components.
There are three Windows versions that do not ship with IIS:
Visual Studio Web Server
If you'd rather not install a full Web Server or you are using Windows XP or Vista Home you can also use the Visual Studio Web Server with the Web Connection Managed Module. The Managed Module is a .NET implementation of the Web Connection connector that works with IIS 7 or ASP.NET 2.0 and can also work with Visual Studio's built in Web Server.
This option requires that Visual Studio or Visual Web Developer is up and running so typically you'll use this opt
There are some manual configuration steps involved in using this option which are described here:
Visual Studio Web Server and the Managed Module
Apache for Windows
Web Connection also work with Apache for Windows and provides basic configuration for Apache through the setup and new project wizards. Some custom configuration may be required.
Web Connection works best with Apache 2.2 or later. You can find the latest version of Apache here:
Web Connection installs a hierarchy of directories as follows:
wconnect classes* - VFP source and direct support files for the framework (required for development) html - HTML sample pages scripts* - The Web Connection ISAPI DLL and CGI executable file templates - The Management Console File templates tools - several useful support tools and classes wwdemo - VFP source for the demos that ship with WWWC wwThreads - VFP Source for the Message Board wwReader - VFP Source for the Message Board Offline Reader application WebControl - The Web Control Framework Samples WebLog - The WebLog sample application
Most of the examples on the demo pages have links to show you the source code required to create that request by clicking on the [Show Code] link on the bottom of the page. At this time you can also start poking around in the code, making a few adjustments, maybe creating a new method and stepping through the code to get an idea what's involved in writing code for Web functionality.
Web Connection is installed from a self-extracting EXE file that allows you to unzip the program files into a directory of your choice. The files extracted are the actual installation files so put these files into a permanent directory, not your temp directory.
Once unzipping is complete the program will automatically launch into the Web Connection Setup program. If this didn't occur automatically you can start the SETUP.EXE program from the Web Connection installation path. This program is required to configure Web Connection for your current Web server installation. Press F1 at any time for detailed instructions on the available options during the install process.
The files unzipped are the Web Connection framework files and your starting point for the installation. Web Connection requires two sets of directories:
These two paths should be completely separate - the Web path underneath the Web root and the application path whereever you choose to install it. Under no circumstances should these point to the same locations.
Other than first installation you don't need to know how this works. Use the defaults and all of this will be set up for you. If you change the defaults and you don't know what these values mean you can run into trouble, but then the issues are described for the help topics for the Setup Wizard.
These settings are the basic settings that must be performed for a Web Connection installation. The Setup program as well as the Web Connection Management Console New Project Wizard perform these task for you automatically, but it's important to understand what happens behind the scenes in case these settings do not work or are accidentally changed. If you or your administrator needs to know what happens with Microsoft Web servers or you want to manually configure settings check out the topic manually configuring Microsoft Web Server.
The first step in configuring Web Connection is to pick the Web server to run on. This choice is very important as it will determine how to configure the server as well copying the appropriate files.
The server selections are straight forward. Web Connection should work fully with an ISAPI compatible Web Server and using file based operation with CGI based Web servers. It's highly recommended you use ISAPI for much improved performance. All Microsoft servers as well as Apache and Website are automatically configured - all other Web servers require manual configuration as outlined in the Setup Program step.
West Wind Web Connection works best Microsoft Internet Information Server 5 or later as well as Peer Web Server (also called Personal Web Server) on Windows NT Workstation. Other platforms and tools also work well, but the development of this product is focused on Internet Information Server and there may be features that don't fully work on other platforms. It's also highly recommended that you use Windows NT rather than Windows 98 to develop your application, both for stability of the dev environment as well as consistency between development and deployment environments.
If you're using IIS you can also select a Web site to install the Web Connection installation on. By default Web Connection uses the default Web site which should serve most situations. Advanced users or ISP's that have multiple sites can use the Advanced IIS Site Selection link to select a Web Site and domain to configure the site on:
The drop down will list all sites installed on the selected domain name or IP address.
When Web Connection runs in file based messaging mode it uses temporary files to pass messages between the Web server and the Visual FoxPro application server. These messages are picked up by the VFP server polling for the files in the temporary directory and it's important that both the ISAPI extension and the VFP server agree on this path. This option writes Path and TempFilePath values to wc.ini and wcDemo.ini (which is the demo application) respectively.
IMPORTANT
This directory must have FULL access for the SYSTEM and IUSR_ (on IIS) annonymous Web Server User Account. When a request comes in in file based messaging the Web server/wc.dll needs to create and write and read the temporary message files. This request runs under standard Web server security so this will typically be the IUSR_ account.
Script File Path
You're asked to provide a physical disk location which can be anywhere. This should be a path that's part of the Web directory structure (ie. this is an HTML path not a Code path). The default will be the server's Web root plus wconnect and this is a consistent choice for this location.
Note
If you see 'Web Server not installed' in the script file path field, make sure that you have indeed selected the correct Web Server on the first page of the Wizard. If you are using IIS4 or 5 and you see this message, you can try explicitly selecting the Web site to install to on the first page by clicking on the Advanced tab and selecting the site.
Virtual Directory Name
This will be the virtual (logical) name for this directory in server relative terms. A virtual is similar to a drive mapping that logically describes an underlying path. It's highly recommended that you do not change this value from its wconnect default. If you do change this value the demos may not work since they use /wconnect as the server relative path to access the Web Connection DLL.
Important note for PWS on Windows 98
If you installed for Personal Web Server on a Windows 98 or 95 machine be sure to reboot your machine, since the registry settings made during install will not take until PWS is completely restarted. Rebooting is the only 'official' way to restart PWS, although you can also kill the process and then restart it.
If you do this manually when you start up next time follow one of these steps:
Note
If you have VFP configured to start up in a specific directory in your VFP Tools|Options settings the shortcut will not do the trick. In that case follow the manual instructions for startup. You can verify your startup path by typingCDinto the command window - it should display the Web Connection Install path.
Once you do this the server form pops up:
Click on the Status button to see the status information of the server that should display some of the information that you specified during the Wizard operation:
You can make additional configuration changes on this status form later on as well as retrieve information about individual requests.
http://localhost/wconnect/default.htm
and access the Web Connection demo page. If this doesn't work please check the Troubleshooting section.
Scroll down to the first request Hello World with Web Connection.
If everything is working OK you should get a response page almost immediately that says Hello World from Visual FoxPro! followed by additional information about some of the server variables exposed by the server.
If this didn't work please see the setup troubleshooting topic.
Otherwise you're in business! Go ahead and browse around the demo page and check out some of the links. Note that most requests have a Show Code link on the bottom of the page that lets you quickly review the Visual FoxPro code that drives the request.
00:07:33 wwDemo~ShowImage - 0.022 00:18:26 wwdemo~TestPage~&Name=Rick&Company=West+Wind - 0.040
Each request that hits the server shows in the main window along with the time that it took to run. At the same time the request gets logged into a log file where you can review and summarize the incoming requests. You can access this log file from the admin page at http://localhost/wconnect/admin.asp and the Show Web Connection Request Log request.
The admin page allows a number of administrative tasks from server monitoring to setting configuration options remotely over the Web to changing operational modes of the server. It's a good idea to shortcut this page in your Favorites list.
The Web Connection Server started with the DO WCDEMOMAIN command runs a VFP program. The demo application is also a PRG file that you can edit. So,
If you go back to Visual FoxPro now you should find the debugger popping up on the SET STEP code that we just inserted:
You can now happily step through the code line by and see the operation of each request as it happens. For example, you can now see the content of the request variables
lcOrigClient=Request.Form("Client")
lcDate1=Request.Form("StartDate")
lcDate2=Request.Form("EndDate")being filled and the SQL WHERE clause being built and then rendering the code with ShowCursor().
As you just saw making a code change is very easy - you simply change the PRG file, save it and start up the server again. You don't need to recompile (although you could recompile the WCDEMO project everytime) and the changes take immediately.
o=CREATEOBJECT("NonExistingObject")Guess what will happen here? The code will fail because this object doesn't exist and a VFP error occurs. VFP pops up an error dialog ontop of the editor with the code highlighted:
This is great for debugging - certainly beats typical COM debugging that doesn't allow you to debug a compiled object at runtime, right.
While this is nice for debugging if this occurs on your live Web site, this would be a problem though. I know you don't make coding mistakes ever <s>, but there are system circumstances or typos etc that do slip into production code. A stop error as we're seeing above would lock the Web Connection server dead in its tracks - it wouldn't be able to take any more requests until the dialog is closed.
In order to work around this Web Connection has a configuration setting that allows you to switch between debug and live modes. You can find this flag in WCONNECT.h:
#DEFINE DEBUGMODE .T.
By default Web Connection ships with this flag set to .T. which makes errors basically stop on the offending line of code, since this is great for debugging. In order to switch this flag into deployment mode set the flag .F. and recompile your project. It's very important that you recompile the project completely with:
BUILD EXE <projname> FROM <projname> RECOMPILE
or by using the Recompile All option from the Build dialog.
Rerun the program now by running the EXE file:
DO WCDEMO
Now re-run the request. You'll find that Web Connection now handles the error and passes back an error page that describes the error on the Web page:
This is obviously much nicer than the server crashing and hanging situation we encountered before. What happens behind the scenes is that the Web Connection error methods kick in and generate this HTML output page. The page can be customized by overriding the wwProcess::ErrorMsg() method in your subclass of it. In fact you can also override the error behavior to perform other tasks on errors, but there's not a lot you can do but display some error info. Once the error page is generated the code returns back to the mainline and the error page is returned to the Web browser.
Note: The Shareware version is precompiled, so the #DEBUGMODE flag cannot be set and recompiled. The Shareware version will always stop on any VFP errors in your code.
This section describes several possible problem scenarios.
Is your Web Server working?
First of all make sure that you can indeed get to the Web Connection demo page by typing http://localhost/wconnect/default.htm (or use the IP address or machine name instead of localhost). If this doesn't work your Web server is not functioning correctly. Check your Web server install docs to get the server working first.
Temp Directory Permission
If you get an error that states that you don't have permissions for your temp directory immediately, make sure that the temp path you've chose supports FULL access for the IUSR_ anonymous Web account. wc.dll requires this in order to write temporary message files when running in file based messaging.
Is the Web Connection Server running?
Next, make sure that the Web Connection server is running in a Visual FoxPro session. The demos are set up to run file based and they require that the Web Connection server is manually started and running in the background. You can do so by starting Web Connection from the desktop or start menu shortcut and using the Web Connection menu to click on Web Connection Demo Server. See Step 4 of the Setup program for details.
Is the ISAPI DLL firing?
If the server is running and still no requests are hitting the server try the following URL:
http://localhost/wconnect/wc.dll?_maintain~ShowStatus
If this URL is not working there's a fundamental problem on the Web Server in accessing the DLL. Follow this link to Manual Server Configuration for more details.
Start by running your Web Connection Server with Do <yourAppMain.prg> and bring up the Status form as shown in the image below. Make sure that the startup path shown in the form matches your actual startup path - if for some reason it doesn't change it to the install directory and Save Settings.
Next bring up the Admin page for your the demo or your application by going to:
http://localhost/wconnect/admin.asp
(or go to your application's admin.asp page). Click on Show and Manage ISAPI settings. We can now compare settings between the Web Connection server and the wc.dll setting the Web Connection DLL is running.

Pay attention the Temp File path and Templates - they should match in both places. Case won't matter, but make sure they are otherwise the same. If they are not we need to sync them.
Changing the your server's settings
To make changes to the application's INI file simply change the value on the Status form and click the Save Server Settings button. When you exist the form these settings should be live. These settings are written into your application's ini file (<yourApp.ini or wcDemo.ini for the demo app).
[Main] Tempfilepath=d:\temp\wc\ Template=WC_
Changing the wc.ini settings
To make changes to the Web Connection ISAPI INI file find wc.ini in your Web directory or the bin directory. Open the file with a text editor or the Visual FoxPro editor.
[wwcgi] Path=d:\temp\wc\ Template=wc_
You'll want to change the Path and Template keys to match the value from the server.
Once this change has been made, go back to the ISAPI DLL Admin page and click on the Re-Read Configuration button, which loads the new settings. Verify that the settings are changed in the status display.

Usually this latter setting is not required, especially if you are installing into the server's Web application tree (ie. \inetpub\wwwroot) because this tree has automatically enabled the Anonymous Web account. If you install outside of this tree however you're responsible for setting the permissions.
The Web Connection Setup, New Project, New Process and Configuration Wizards all automatically apply these settings for IIS.
These parameters are passed (by the demo at least as: wc.dll?Project~Method~Parameters). The Project name is added in the wcDemoServer :: Process() method in the CASE statement. The second parameter is handled by your processing code in the wwProcess :: Process() method and needs to correspond to a method in the class that handles requests. If the class does not exist you get the error.
To fix make sure you have set up an entry in the Server's Process CASE statement and you have a matching method in your custom Process() class. For more info, see the section on Your First Web Request.
Note to Apache Users:
If you switched to Apache from IIS make sure you add the following to your ServerMain.prg file's server class:
Without this setting Apache returns invalid script map path information which the above class fixes.DEFINE CLASS wcDemoServer AS WWC_SERVER OLEPUBLIC cRequestClass = "wwApacheRequest" ...
Double check the installation in the Web server's configuration. With IIS bring up the IIS Management Console and check that the /wconnect virtual directory was created. Make sure that the directory has Execute (Script and Execute) rights enabled.
The setup program and the various Project and Process Wizards should create all the Web site configuration settings for you automatically. But under certain circumstances it's possible that the new settings don't take. In particular you may find that virtual directory and script map settings didn't take.
For those of you that want to know or don't trust utilities here's how to do the dirty work by hand.
For manual installation on IIS 7 or later please see:
IIS 7 Configuration
For manual installation on IIS 6 and Windows 2003
Windows 2003 Configuration
Creating a virtual directory
If the directory exists below the Web root, you may not be able to create the virtual through the Wizard as the MMC sees a naming conflict with the existing directory. In this case simply select the directory from the Web site's directory listing and right click, then click Properties. Go down to the Application Settings setting and click on the Create button to create the virtual directory. As above check the Execute Permission to Scripts and Executables if you have wc.dll in this directory, otherwise set it to Scripts.

Script maps by default are installed on the new virtual directory only, but you can optionally install them at the root of the server in which case they are visible throughout the entire Web site. Typically you'll want local script maps only, global scriptmaps can be useful if your application is site-wide or wants to run in various different virtual directories.
Make sure your temp directory has full rights for IUSR_
It's vital that you configure the directory that you choose for Web Connection temp file creation (set in wc.ini with PATH= and your app's INI file as TEMPFILEPATH=) has FULL rights configured for the IUSR_ account. If you're running NTFS use the NT Directory permissions to configure this. With FAT set up the TEMP path for sharing and make sure that IUSR_ or Everyone is included in the list.
Note: The temp path does not have to be your system TEMP path, although that's the logical place to put this file. I personally prefer to use a path such as d:\temp\wc so the directory is isolated and this is the installation default.
DO CONSOLE WITH "SPLASH"
o=CREATE("wwWebServer","IIS4")
o.CreateVirtual("wconnect","c:\inetput\wwwroot\wconnect\")
o.CreateScriptMap(".wc","c:\inetput\wwwroot\wconnect\wc.dll")
The following server types are supported:
IIS6 - IIS6 is used under Windows Server and sets up a Web Connection Application Pool
IIS4 - IIS4 and IIS5 and PWS 4 and 5 under Windows NT
IIS3 - IIS 3 and PWS 3 under Windows NT
PWS4 - Personal Web Server 4.0 Windows 98
PWS3 - Personal Web Server 1.0 and 3.0 Windows 95
These are the tools the Web Connection Setup uses internally to configure the server, so if Setup fails to install settings it's possible that the wwWebserver class and the Console will not do the trick and you have to follow the manual steps outlined above.
I highly recommend you use the Server Configuration Wizard for these tasks as it is the best way to make sure all the necessary settings are made.
If you have an existing application and you want to configure it for IIS 6 and later you can:
Important Note:
Windows Server 2003 is locked down by default to not allow any external extensions or applications to run. Instead you get 404 file not found errors. If this is the case open the IIS Management console and either allow 'Allow all unknown ISAPI extensions' to allowed or add the Web Connection DLL:

Rather than changing the way IIS works by default the best choice for configuration is to use a custom Application Pool and configure it for our Web Connection applictions. An Application Pool is a new feature in IIS 6 that isolates a Web application or more than one into a separate process. These highly efficient processes (which work like Daemon services on Unix) are managed by the core IIS service and provide a number of advanced features such as metrics and recycling that are very useful for guaranteeing server uptime.
Each application domain is configured individually and there are many options health features. The fetaure that is most important for Web Connection is the Identity that the AppPool runs under. By default this is NETWORK SERVICE, but we need to change this to Local System. To do this:
Next you go to or create your virtual directory for your your application and select the West Wind Web Connection Pool.
Make sure that 'Verify that file exists' is not checked!

IIS 6 uses a concept called application pools which is basically a worker process that handles each incoming request. IIS 6 uses Kernel mode HTTP drivers that talk directly to these processes improves performance of IIS considerably. Use of the separate worker processes in IIS 6 means that COM+ is no longer involved which has been the core problem for firing the Web Connection servers (DCOM and COM+ incompatibilities). It's also much easier to debug the ISAPI code now than was previously possible resulting in an easier development environment for the wc.dll ISPAPI extension moving forward.
There are a number of new features in Windows 2003 that deal with making sure that the service or pool keeps on running. This is really useful for automatically cycling the Web Server process and a few other settings. The Application can be set up to automatically restart itself after x number of hits, after a certain time, or if a certain memory limit has been hit.
The IIS Metabase in IIS 6 is an XML file - much easier to configure this way and easier to see what's actually available for configuration. ADSI still works as before although new features like the AppPools aren't documented at this time.
Note:
It's crucially important that you have these components installed before you start installing Web Connection!
Here are the required components for Web Connection:

The figure above highlights the critical components that are used by Web Connection and are absolutely required. THere are a few additional checks in the above that will be useful in the future which is ASP.NET and .NET Extensibility.
The most important settings are:
The ISAPI extension support enables the Web Connection ISAPI extension to run - without this setting nothing will work. IIS Metabase support ensures that the COM based configuration of the Web Server can be performed through the Web Connection Management Console for the New Project and Server Configuration Wizards.
I'd also recommend installing ASP.NET support as there will be more integration between ASP.NET and Web Connection in future versions.
In all cases you should use the IIS 7 server setting from the server type drop down.

From there forward all the configuration options will work as any other of the Wizards for virtual directory configuration etc. This should be the easiest way to configure a Web application quickly as all of these mechanisms allow creationg of a virtual directory, configuring script maps and adding the Web Connection ISAPI extension into the allow application server application list.
Create Virtuals:
*** Using the Console - last parameter is the IIS Admin path under which virtual is created DO Console WITH "Virtual", "WebDemo","c:\westwind\webdemo",.F.,"IIS7","IIS://localhost/W3SVC/1/ROOT" *** Interactive DO Console WITH "Virtual","UI"
Create Scriptmaps:
*** Using the Console DO Console WITH "ScriptMap", ".wxx","c:\westwind\webdemo\bin\wc.dll",.F.,"IIS7","IIS://localhost/W3SVC/1/ROOT/WebDemo" *** Interactive DO Console WITH "ScriptMap", "UI"
Note scriptmap creation will also register the ISAPI extension with the ISAPI restriction list.
Although a separate Web Connection Application Pool is not required it is recommended. The main reason is that Web Connection should be run in the System security context rather than the default Network Service security context and this setting is configured at the Application Pool level. This setting isn't required but if you don't run in System Context additional configuration may be required to ensure that Network Serivce (or whatever account you choose) has rights in several locations (Temp File directory, DCOM permissions for COM operation etc.).
To create an Application Pool in IIS 7:

Once you've created the Application Pool select it in the list and click on Advanced Settings. In the property sheet that appears set the Identity for the Application Pool to LocalSystem.

You can also configure various other settings such as the process recycling, idle timeout and various other flags. Note that if you are running on a 64 Bit machine you should also set the Enable 32 Bit applications flag to True to enable the Web Connection ISAPI DLL which is a 32 bit application.

Once the virtual has been created select the Authentication option in the virtual's configuration.
Enable:

The extension needs to be explicitly enabled:

http://www.west-wind.com/wconnect/bin/wc.dll?wwDemo~TestPage
are not allowed. This can be a problem for backwards compatibility if you use the bin path directly.
There are relatively easy workarounds for this problem:
Script maps can be configured in the service manager as follows:


Here's what a Web.config for the WebDemo project looks like:
<?xml version="1.0" encoding="UTF-8"?> <configuration> ... omitted <system.webServer> <handlers> <add name="WebDemo-wcsx" path="*.wcsx" verb="GET,POST" modules="IsapiModule" scriptProcessor="c:\westwind\webdemo\bin\wc.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" /> <add name="WebDemo-wp" path="*.wp" verb="GET,POST" modules="IsapiModule" scriptProcessor="c:\westwind\webdemo\bin\wc.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" /> <add name="WebDemo-wc" path="*.wc" verb="GET,POST" modules="IsapiModule" scriptProcessor="c:\westwind\webdemo\bin\wc.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" /> <add name="WebDemo-wwsoap" path="*.wwsoap" verb="GET,POST" modules="IsapiModule" scriptProcessor="c:\westwind\webdemo\bin\wc.dll" resourceType="Unspecified" requireAccess="Script" responseBufferLimit="0" /> </handlers> </system.webServer> </configuration>
This can be especially useful for copying script map entries if you need to service a bunch of different script map extensions and it's much quicker to cut and paste these entries than adding them individually in the Service Manager.
Here's a quick review of the issues involved:
%1 is not a valid Win32 application.
(note that if you use IE default error reporting it will not actually show this error because the error message is too short - you'll only see the 500 Internal Error Page)
When running IIS 7 you will get a server based exception and if debugging is enable you will get an Internal Server Error with an ExecuteHandlerRequestHandler error message which looks like a security violation.
This indicates that the ISAPI extension is called from a 64 bit server instance. To fix this issue you need to do the following:
The flag is set in the Application Pool Settings Manager with the Advanced Options:

DO CONSOLE WITH "ENABLE64BIT"
to turn it off:
DO CONSOLE WITH "ENABLE64BIT","OFF"
You can also run CONSOLE.EXE from the Windows Command prompt:
CONSOLE.EXE ENABLE64BIT CONSOLE.EXE ENABLE64BIT OFF
Reconfigure ASP.NET for the proper 32 or 64 bit version
In addition you may have to fix ASP.NET if it is installed on the server. ASP.NET 2.0 installs an ISAPI filter and that filter needs to be tied to either the 32 bit .NET runtime or the 64 bit version. If the wrong filter is installed you will get a Service is Unavailable error as the Application Pool crashes basically on any request and shuts down.
To set up ASP.NET for 32 bit:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727>aspnet_iisreg -i
To set up ASP.NET for 64 bit:
C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727>aspnet_iisreg -i
Note that this ASP.NET configuration is REQUIRED even if you don't use ASP.NET, but if it is enabled. To check for this go to:
IIS Service Manager | Web Sites | ISAPI Filters
In the list you should see the ASP.NET ISAPI filter if it's active. If it is there you will need to run the above command line appropriate for this version. Or if you don't use ASP.NET at all you can just remove the filter.
The module works with ASP.NET 2.0 on IIS 6 or as a native HttpHandler in IIS 7.0 and it works without any configuration changes both in 32 and 64 bit mode.
For more information please check out Using the Web Connection Managed Module.
Web Connection provides a custom Apache ISAPI module (mod_webconnection_isapi.so and mod_webconnection_isapi_20.so) that can be found in the \scripts directory of your Web Connection installation. There are two versions: The default 2.2 compatible version and a 2.0 specific version (mod_webconnection_isapi_20.so). The Web Connection console will pick the right module based on the version of Apache installed. If you manually install make sure you pick the correct version of these module files for copying into the Apache Modules directory.
This custom Apache provides the following:
Please note that if you plan on using Apache, you should be familiar with Apache Configuration and security. It is your responsibility to lock down Apache server and your application and provide common customization features. The Web Connection installer only provides basic hook ups for Apache operation of Web Connection.
The Wizards will handle the following:
Copying the Web Connection Apache Module
The Web Connection module is found in the /scripts directory of the Web Connection installation. You should always copy this directory with your application to the server so the scripts directory is available to copy the files from within it to the server. To copy the file:
COPY FILE "<webconectionInstallFolder>\scripts\mod_webconnection_isapi.so" TO; "<ApacheRoot>\modules\mod_webconnection_isapi.so"
If you're using a version of Apache prior to 2.2 use:
COPY FILE "<webconectionInstallFolder>\scripts\mod_webconnection_isapi_20.so" TO; "<ApacheRoot>\modules\mod_webconnection_isapi.so"
Create an Apache virtual directory
Typically virtual directories are created underneath the Apache\htdocs directory. This Web path will hold all of your Web related files - HTML files, images, script pages etc.
Into this directory you should copy the standard Web Connection related project files which are stored under <wcInstall>\HTML which is the Web template for the project.
Copying the Web Connection DLL
The most important file for the Web installation is the Web Connection ISAPI DLL (wc.dll). If you copied from a template this file will already be there otherwise you can find it here:
COPY FILE TO "<webconnectionInstallFolder\scripts\wc.*" TO ; "<WebDirectory>\BIN\wc.*"
This copies both wc.dll and wc.ini configuration file. wc.ini holds Web Connection configuration information in an INI file format and you'll need to confgure this file to match the settings in your server file. Specifically make sure you set the path (which is the temp file path for file based messaging) and the Template which needs to match the settings configured in your Web Connection server (<yourapp>.ini)
;*** THIS DIRECTORY MUST HAVE READ AND WRITE ACCESS FOR THE Path=d:\temp\wcapache\ ;*** Message File Template (1st 3 letters) ;*** Default is "wc_" Only needed if using a different template Template=WC_
Modifying httpd.conf
Apache configuration is handled through the httpd.conf file which lives in the /conf folder of the Apache Configuration. Web Connection adds a few entries to this file. There are a couple of global settings and a host of settings specific to each virtual directory/application that you configure.
At the bottom of the file add the following:
#*** WEB CONNECTION MODULE CONFIGURATION LoadModule webconnection_isapi_module modules/mod_webconnection_isapi.so #*** END WEB CONNECTION MODULE CONFIGURATION #*** WEB CONNECTION VIRTUAL - wconnect #*** WEB CONNECTION SCRIPT ALIAS ScriptAliasMatch (?i)^/wconnect/.*\.(wc|wcs|wcsx|wwsoap|wwd|blog|pho|wwr)$ "C:\Program Files\Apache2.0\Apache2\htdocs\wconnect\wc.dll" #*** END WEB CONNECTION SCRIPT ALIAS Alias /wconnect/ "C:/Program Files/Apache2.0/Apache2/htdocs/wconnect/" <directory "C:/Program Files/Apache2.0/Apache2/htdocs/wconnect/"> DirectoryIndex default.htm Options ExecCGI # AddHandler isapi-handler dll AddHandler webconnection-isapi-handler dll #*** WEB CONNECTION VIRTUAL SCRIPT MAPS AddType application/webconnection-scriptmap .wc .wcs .wcsx .wwsoap .wwd .blog .pho .wwr Action application/webconnection-scriptmap "/wconnect/wc.dll" #*** END WEB CONNECTION VIRTUAL SCRIPT MAPS </directory> #*** END WEB CONNECTION VIRTUAL - wconnect #*** WEB CONNECTION VIRTUAL - wwthreads #*** WEB CONNECTION SCRIPT ALIAS ScriptAliasMatch (?i)^/wwthreads/.*\.(wwt|wc)$ "C:\Program Files\Apache2.0\Apache2\htdocs\wconnect\wc.dll" #*** END WEB CONNECTION SCRIPT ALIAS Alias /wwthreads/ "C:/Program Files/Apache2.0/Apache2/htdocs/wwthreads/" <directory "C:/Program Files/Apache2.0/Apache2/htdocs/wwthreads/"> DirectoryIndex default.htm Options ExecCGI # AddHandler isapi-handler dll AddHandler webconnection-isapi-handler dll #*** WEB CONNECTION VIRTUAL SCRIPT MAPS AddType application/webconnection-scriptmap .wwt .wc Action application/webconnection-scriptmap "/wwthreads/wc.dll" #*** END WEB CONNECTION VIRTUAL SCRIPT MAPS </directory> #*** END WEB CONNECTION VIRTUAL - wwthreads
The comment lines (#) are optional but recommended as they are placeholders for the Web Connection configuration routines that allow you to update the settings using the Wizards or programmatic tools to configure the server. If you add the comments for auto-configuration make sure the comment lines are EXACTLY as above (ie. cut and paste!).
The key features are:
LoadModule loads the Web Connection Apache module. This is a global setting and should only be specified once in the file.
ScriptAliasMatch is used to deal with script mapping. It routes any custom extension you'd like to configure to the Web Connection ISAPI DLL. NOTE: it's crucial that this directive is declared before the Alias for the virtual is defined - otherwise you will get File Not Found errors on any requests that access non-file backed 'scripts'.
Alias creates a Virtual directory. It maps a logical/virtual path to a physical path.
The <directory> tag contains configuration settings for the specific directory on disk. It specifies the default document(s), and that this directory supports dynamic script operation (ExecCGI). It also sets up the Web Connection ISAPI DLL as a script handler for any files that map to the extensions specified in the AddType command. Action then maps the type specified to the Web Connection ISAPI DLL as the script handler. These script handlers are actually not required if you use a ScriptAliasMatch as above, but they are left in here in case ScriptAliasMatch is missing or misconfigured - AddType will catch any scriptmapped requests that have a backing file.
DO WCONNECT SET CLASSLIB TO WebServer ADDITIVE oWeb = CREATEOBJECT("wwWebServer") oWeb.cServerType = "APACHE" *** Create a virtual directory oWeb.CreateVirtual("WebDemo","d:\westwind\webdemo") oWeb.CreateScriptMap(".wp","d:\westwind\webdemo\bin\wc.dll","WebDemo") oWeb.CreateScriptMap(".wpp","d:\westwind\webdemo\bin\wc.dll","WebDemo") *** Edit the .Config file lcConfigFile = oWeb.GetWebRoot() + "conf\httpd.conf" GoUrl(lcConfigFile) && Opens in Notepad for editing
Apache returns some server variables slightly differently than IIS does and so a special subclass of the wwRequest class called wwApacheRequest is used to handle these differences. IIS returns some platform specific server variables that are not returned by Apache - but most of these are truly platform specific and rarely used so this should not be a problem.
The wwApacheRequest class handles path fixup for requests by explicitly checking paths and trying to automatically fix up the physical path to match the true physical path of a given script.
To use the wwApacheRequest class you can simply assign the cRequestClass in the your main wwServer class which is contained in <yourApp>Main.prg. The following code demonstrates:
DEFINE CLASS WebdemoServer AS WWC_SERVER OLEPUBLIC cRequestClass='wwApacheRequest' ...
Alternately you can also override this globally using the following flag in your WCONNECT_OVERRIDE.H file:
#UNDEFINE WWC_REQUEST
#DEFINE WWC_REQUEST wwApacheRequest
The former is a little less intrusive and isolates the change to the current application, while the latter can be easier if you need to do this with multiple applications as the flag is global to all Web Connection applications.
Set the CallCoInitialize flag in wc.ini
Starting with Version 4.50 Web Connetion no longer calls CoInitialize by default on COM requests by default. This fixed a number of issues with IIS as IIS had some issues with multiple calls to CoInitialize and potential mismatched CoUninitialize calls. IIS automatically calls CoInitialize for each thread, so there's no need to do it again.
Apache however does not do this, so we need to tell the Web Connection ISAPI dll to explicitly to call CoInitialize/CoUninitialize. To do so we set the CallCoInitialize flag in the wc.ini file:
[Automation Servers] ;*** Severloading - 0 - Normal 1 - Round Robin ServerLoading=1 ;*** KeepAlive 0 - Normal 1 - Force extra COM reference to keep alive KeepAlive=1 Server1=webDemo.webDemoServer ;Server2=webDemo.webDemoServer ;*** Determines whether CoInitialize for COM objects ;*** Set this option to 1 only if your servers do not ;*** load and given an error message to the effect ;*** that COM is not initialized. Should only be needed ;*** on ancient or non-Microsoft Web Servers. CallCoInitialize=1
Your wc.ini file is found in the same directory as wc.dll which will be your Web virtual directory usually in the BIN path.
To work around these issues and provide the basic security for locking down administration functions in the Web Connection DLL, the Web Connection Apache ISAPI Module provides Windows based Basic Authentication. When using the custom module, programmatic Basic Authentication works just like it does in IIS by authenticating against Windows User accounts rather than using Apache's password files.
This lets you set security in the wc.ini configuration file:
;*** Account for Admin tasks REQUIRED FOR ADMIN TASKS ;*** NT User Account - The specified user must log in ;*** Any - Any logged in user ;*** - Blank - no Authentication AdminAccount=Any
Check with your Apache Administrator for more information on setting up Web Server authentication for requests.
*** Load the Web Connection class libraries
DO WCONNECT
*** Load the server - wcDemoServer defined below
goWCServer=CREATE("wcDemoServer")
*** If running a CGI Web server uncomment the following line
goWCServer.oRequest = CreateObject("wwShellCGI")
Here is a list of advantages of using the module:
There's also one downside to using the module which relates to the way that ASP.NET and IIS 7 separate IIS applications:
This means if you have two separate applications that both use the same COM server they will create two sets of servers rather than a single set as the Web Connection ISAPI DLL did as long as script maps pointed to the same DLL.
There's a workaround for this scenario: You can create a hierarchy of directories that are based on a physical disk layout and so don't need to rely virtual directories for separation. So if the root is configured for the module any non-virtual directories below it share that ASP.NET AppDomain. It requires some forethought and organization which is easy to do knowing this issue exists. However, it can be potentially difficult to achieve if you already have existing shared applications in place.
Here's how to set up a new project and switch to the Managed Module:

By default the web.config file that installs with the new project has the module hook ups commented out which in turn results in the ISAPI DLL being used. To switch to using the module open web.config and edit the following section:
<?xml version="1.0"?> <configuration> <system.webServer> <handlers accessPolicy="Script, Execute, Read"> <!-- IIS 7 in Integrated Mode --> <add name="*.wp_wconnect" path="*.wp" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wc_wconnect" path="*.wc" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wcs_wconnect" path="*.wcs" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wcsx_wconnect" path="*.wcsx" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wwsoap_wconnect" path="*.wwsoap" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.blog_wconnect" path="*.blog" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wwd_wconnect" path="*.wwd" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <!-- end IIS 7 in Integrated Mode --> </handlers> </system.webServer> </configuration>
Note there are additional entries in web.config that also need to be there, but these items will be already set. The above section nees to be uncommented in the XML (just remove the <!-- before the <add and after the last />).
This section basically maps each script map to the managed module. This setting overrides any ISAPI handler mappings, so you don't need to do anything else. If you want to switch back to the ISAPI handler, simply uncomment these mappings.
You will also need to ensure that the .NET 2.0 runtime is installed.
Here's how to set up a new project and switch to the Managed Module:
This basically maps the Web Connection extensions to ASP.NET in your virtual directory, so if the script map is used it will fire through ASP.NET 2.0. Next we'll need to hook up the Web Connection Connector Handler by modifying a setting in web.config (in your Web directory's root).
<?xml version="1.0"?> <configuration> <system.web> <httpHandlers> <!-- pre IIS 7 or IIS 7 in non-integrated mode NOTE: you still need to set up scriptmaps to c:\windows\Microsoft .NET\v2.0.50727\aspnet_isapi.dll --> <add verb="*" path="*.wp" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wc" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wcsx" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wcs" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wwsoap" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <!-- End pre IIS 7 --> </httpHandlers> </system.web> </configuration>
The VS Web Server can also be run without Visual Studio actually running optionally.
Once set you can simply open the project in Visual Studio and press Run to execute the Web application (or View In Browser on the Default.htm page) or press Ctrl-F5 to start the Visual Studio Web server on your Web project. You will likely get a compilation error due to the fact that you have Visual FoxPro code in your markup pages which won't compile - ignore the error and set the checkbox to to not show the dialog next time.
From thereon in everything should just work. Note if you Run the Web application you will get many errors potentially - because these projects aren't really ASP.NET code this is normal and you should simply ignore the errors and choose Yes to run anyway to start the site.
The server stays running in the task tray until you explicitly shut it down or close Visual Studio. You can see the port number when hovering over it or clicking on the icon which brings up a small configuration form.
Please note that Web Connection's Show in Web Browser will not work unless you modify the AppSettings key in web.config:
<appSettings> <add key="FoxProjectBasePath" value="c:\wwapps\wc3\"/> <add key="WebProjectBasePath" value="c:\westwind\wconnect\webcontrols\"/> <add key="WebProjectVirtual" value="http://localhost:63841/wconnect/webcontrols/"/> <add key="WebBrowser" value=""/> </appSettings>
But keep in mind that you'll have to change the port each time you restart the VS Web Server. This will be addressed in Visual Studio 2008 which includes an option to set a fixed port for the Web server.
DO CONSOLE with "LAUNCHCASSINI","c:\websites\webdemo","81","/WebDemo"
or if you want to manually set these settings:
DO CONSOLE with "LAUNCHCASSINI"
which brings up the server form:

You can click on the link to bring up a browser at this location. You can minimize the appication to the task tray so the Web Server window stays out of your way.
A Url to the server will be:
http://localhost:81/WebDemo/Default.htm
and you should specify whatever path you choose in your web.config configuration for the WebProjectVirtual:
< add key="WebProjectVirtual" value="http://localhost:81/wconnect/webcontrols/"/>
I recommend you create a small PRG file - maybe called LaunchWebServer.prg - and add:
DO CONSOLE with "LAUNCHCASSINI","c:\websites\webdemo","81","/WebDemo"
to start your server quickly and easily.
Configure the Start Page
The settings in the figure above should be the default except for the default.htm homepage but you can specify any page that you like. The start page can be invoked if you run the site or press Ctlr-F5.
Configure web.config to use the Managed Module
Finally we need to tell the VS Web Server that we want our application extensions to be mapped to the Web Connection module. Add the following to web.config in the project:
<?xml version="1.0"?> <configuration> <configSections> <system.web> <compilation defaultLanguage="C#" debug="false"> <buildProviders> <add extension=".wcsx" type="System.Web.Compilation.PageBuildProvider"/> <add extension=".wcsctl" type="System.Web.Compilation.PageBuildProvider"/> </buildProviders> </compilation> <httpHandlers> <add path="*.wcsx" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add path="*.tt" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add path="*.wc" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add path="*.wwsoap" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> </httpHandlers> </system.web> </configuration>
Both the build providers and the HttpHandlers are required to make this work. Add any script maps you might require in the httpHandlers section. Note that using either Cassini or the Visual Studio Server requires no further configuration as the server runs ALL content through its ASP.NET pipeline. So unlike IIS configuration which requires addition script mapping for ASP.NET the above is all that's needed.
To work around this make sure you set the AdminAccount key in web.config to blank ("") so no authentication is applied.
A full Web.Config looks something like this:
<?xml version="1.0"?> <configuration> <configSections> <section name="webConnectionConfiguration" type="System.Configuration.NameValueSectionHandler,System,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> <section name="webConnectionErrorPages" type="System.Configuration.NameValueSectionHandler,System,Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" /> </configSections> <appSettings> <add key="FoxProjectBasePath" value="c:\wwapps\wc3\" /> <add key="WebProjectBasePath" value="C:\westwind\WebDemo\" /> <add key="WebProjectVirtual" value="http://localhost/WebDemo" /> <!-- The efault browser used. Blank IE Automation, otherwise specify browser path --> <add key="WebBrowser" value="" /> <add key="xWebBrowser" value="c:\program files\firefox\firefox.exe" /> </appSettings> <system.web> <compilation defaultLanguage="c#" debug="false"> <buildProviders> <add extension=".wcsx" type="System.Web.Compilation.PageBuildProvider" /> <add extension=".wp" type="System.Web.Compilation.PageBuildProvider" /> </buildProviders> </compilation> <trust level="Full" /> <httpHandlers> <!-- pre IIS 7 or IIS 7 in non-integrated mode NOTE: you still need to set up scriptmaps to c:\windows\Microsoft .NET\v2.0.50727\aspnet_isapi.dll --> <!--<add verb="*" path="*.wp" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wc" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wcsx" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wcs" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/> <add verb="*" path="*.wwsoap" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule"/>--> <!-- End pre IIS 7 --> </httpHandlers> </system.web> <system.webServer> <handlers accessPolicy="Script, Execute, Read"> <!-- IIS 7 in Integrated Mode --> <add name="*.wp_wconnect" path="*.wp" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wc_wconnect" path="*.wc" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wcsx_wconnect" path="*.wcsx" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wcs_wconnect" path="*.wcs" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <add name="*.wwsoap_wconnect" path="*.wwsoap" verb="*" type="Westwind.WebConnection.WebConnectionHandler,WebConnectionModule" preCondition="integratedMode,runtimeVersionv2.0" /> <!-- end IIS 7 in Integrated Mode --> <!-- IIS 7 non-integrated mode ScriptMappings --> <!--<add name="wp_ISAPI" path="*.wp" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" /> <add name="wc_ISAPI" path="*.wc" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" /> <add name="wcsx_ISAPI" path="*.wcsx" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" /> <add name="blog_ISAPI" path="*.blog" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" /> <add name="wwd_ISAPI" path="*.wwd" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" resourceType="Unspecified" />--> <!-- end IIS 7 non-integrated mode ScriptMappings --> </handlers> </system.webServer> <webConnectionConfiguration> <!-- NOTE: These settings apply only to the Web Connection Managed Module! --> <add key="Timeout" value="60" /> <add key="PollTimeout" value="100" /> <add key="InputPostBufferSize" value="65356" /> <add key="PostBufferLimit" value="0" /> <add key="TempPath" value="c:\temp\wc\" /> <add key="TempFilePrefix" value="WC_" /> <add key="MessagingMechanism" value="File" /> <add key="AdminAccount" value="ANY" /> <add key="AdminPage" value="~/admin/admin.asp" /> <add key="ExeFile" value="c:\wwapps\wc3\WebDemo.exe" /> <add key="UpdateFile" value="" /> <add key="LogDetail" value="False" /> <add key="ValidateRequest" value="False" /> <add key="ComServerProgId" value="WebDemo.WebDemoServer" /> <add key="ComServerLoadingMode" value="LoadBased" /> <add key="ServerCount" value="2" /> <add key="AutoStartServers" value="False" /> <add key="MessageDisplayFooter" value="<small>Error generated by Web Connection IIS Connector Module</small>" /> </webConnectionConfiguration> <webConnectionErrorPages> <!-- NOTE: These settings apply only to the Web Connection Managed Module! --> <add key="Exception" value="" /> <add key="OleError" value="" /> <add key="Timeout" value="" /> <add key="NoOutput" value="" /> <add key="Busy" value="" /> <add key="Maintenance" value="" /> <add key="InvalidRequestId" value="" /> <add key="TranmitFileFailure" value="" /> <add key="PostBufferSize" value="" /> </webConnectionErrorPages> </configuration>
These settings are persisted in the WebConnectionConfiguration section of the Web.config file and be set there.
<webConnectionConfiguration> <!-- NOTE: These settings apply only to the Web Connection Managed Module! --> <add key="Timeout" value="60" /> <add key="PostBufferLimit" value="0" /> <add key="TempPath" value="c:\temp\wc\" /> <add key="TempFilePrefix" value="WC_" /> <add key="MessagingMechanism" value="File" /> <add key="AdminAccount" value="ANY" /> <add key="AdminPage" value="~/admin/admin.asp" /> <add key="ExeFile" value="c:\wwapps\wc3\WebDemo.exe" /> <add key="UpdateFile" value="c:\temp\updates\WebDemo.exe" /> <add key="LogDetail" value="False" /> <add key="ValidateRequest" value="False" /> <add key="ComServerProgId" value="WebDemo.WebDemoServer" /> <add key="ComServerLoadingMode" value="LoadBased" /> <add key="ServerCount" value="2" /> <add key="AutoStartServers" value="False" /> <add key="MessageDisplayFooter" value="<small>Error generated by Web Connection IIS Connector Module</small>" /> </webConnectionConfiguration>
public class AppConfiguration : wwAppConfiguration
| Member | Description | |
|---|---|---|
![]() |
AdminAccount | The account that is allowed access to the administration functions when authenticated. |
![]() |
AdminPage | The adminstration page in the application. Allows use of ~ for the application path. |
![]() |
AutoStartServers | Determines whether servers are automatically started when the first hit comes into the module. Useful primarily for file based operation which starts up the EXE server |
![]() |
ComServerLoadingMode | Deterimines how servers are processing requests. Round Robin simply goes through each of the servers one after the other while LoadBased always starts with the first server. |
![]() |
ComServerProgId | The ProgId of the COM server to be loaded |
![]() |
ExeFile | Name of the EXE file for the server application. |
![]() |
LogDetail | Determines whether request data is logged in detail. |
![]() |
MessageDisplayFooter | A default footer message displayed on the bottom of the Module's generic messages |
![]() |
MessagingMechanism | Determines how messaging works in Web Connection |
![]() |
PostBufferLimit | Max size of the POST buffer - if bigger request is aborted |
![]() |
ServerCount | Determines how many Com instance of the server are loaded in Com messaging mode. |
![]() |
TempFilePrefix | The temp file prefix for file based message files |
![]() |
TempPath | The Path where message files are written for file based messaging |
![]() |
Timeout | The request timeout in seconds |
![]() |
UpdateFile | The Update EXE file from which the Exe file can be hot swapped |
Can be any account name, or ANY for any authenticated user. You can also specify a list of authenticated users in a comma delimited list.
public string AdminAccount
public string AdminPage
public bool AutoStartServers
public ComServerLoadingModes ComServerLoadingMode
public string ComServerProgId
Used for hot swapping functionality and killing the servers when shutting down. The module also uses the file name to retrieve version information as well for loading file based instances. It's fairly crucial that this value is set correctly.
public string ExeFile
public bool LogDetail
public string MessageDisplayFooter
File Com
public MessagingMechanisms MessagingMechanism
0 - means no checks are performed. Note that ASP.NET settings may override
public int PostBufferLimit
public int ServerCount
public string TempFilePrefix
public string TempPath
public int Timeout
public string UpdateFile
The filenames can either be expressed as relative Web Paths: messages/Maintenance.htm ~/messages/Maintenance.htm
or as absolute physical paths: c:\westwind\wconnect\messages\maintenance.htm
Whatever path files are read from requires that the account running the application (typically SYSTEM) has read access.
System.Object
Westwind.Tools.wwAppConfiguration
Westwind.WebConnection.AppErrorMessagePages
public class AppErrorMessagePages : wwAppConfiguration
| Member | Description | |
|---|---|---|
![]() |
Busy | Page displayed only for COM messaging when no server instance can be retrieved when all instances are already busy processing requests. |
![]() |
Exception | Page to display when an Execption occurs during the server call. Used for file based messaging. |
![]() |
InvalidRequestId | Page to display when the request id doesn't match |
![]() |
Maintenance | Page displayed when the server is in maintenance mode and not accepting requests while the MaintMode flag is set. |
![]() |
NoOutput | Page displayed when the server application returned no output to the module. |
![]() |
OleError | Exception fired when a COM Server call fails. This is specific to a failure in the COM server operation - typically this will be an Invokation error or a COM security error. |
![]() |
PostBufferSize | Error displayed if the PostBufferSize is exceeded |
![]() |
Timeout | Page displayed when a request times out for taking too long to process |
![]() |
TranmitFileFailure | Page displayed if TransmitFile fails to find or access the requested file |
public string Busy
Exception is also the 'generic' failure message that is displayed if an internal error occurs in the module processing.
public string Exception
public string InvalidRequestId
public string Maintenance
public string NoOutput
public string OleError
public string PostBufferSize
public string Timeout
public string TranmitFileFailure
After you've deployed files the easiest way to perform the remaining tasks is by using the Server Configuration Wizard, which lets you do the following:
If you created your application with the New Project Wizard you can simply do:
DO BLD_<yourProject>
This will compile the server and register it for interactive DCOM use. Alternately you can just compile your EXE file directly:
BUILD EXE <yourProject> FROM <yourProject>
Once compiled your server can now be run either from Explorer or is accessible as a COM object. To quickly test COM operation try this from the Command window:
oServer = CREATEOBJECT("<yourProject>.<yourProject>Server") ? oServer.ProcessHit("query_string=wwMaint~FastHit")
The first line should bring up your server as a window. The second line will simulate a request in the server and should return an HTTP response string.
Make sure your COM server is marked for SingleUse
One thing you should check if you are running a VFP version prior to 8.0 is to make sure that your server is compiled as a SingleUse COM server. To check this:
Summary:
This can involve installing from an installer, simply copying files to a server or FTP'ing files to a server.
Note that a first time installation requires someone at the server to run the installation.
The following need to be moved to the server:
YourApplication.exe
YourApplication.ini
wwIPStuff.dll
zlib.dll
wwImaging.dll (required only if you use the imaging function in wwAPI)msvcr71.dll (for Apache only. should be copied into the System directory if it doesn't exist)
Console.exe
.\SCRIPTS
.\TEMPLATES
.\TOOLS\DComPersmissions.exe (can go into the main directory)
Use the script maps
The New Project Wizard also creates a scriptmap for your application automatically - it's highly recommended that you use that scriptmap extension instead of referencing the DLL directly so that the application is more portable.
Tip!
Whenever possible try to set up your project in such a way that it mimicks the final setup on the server. Use the same directory structures and data paths for example. Although this is not required this setup can make it much easier to fix problems and synchronize a development and live installation. Always make sure that all paths (both application and Web paths) are relative to some base path or the current path. This will ensure your application is portable when moved to different directory.
Take note early on on how the application will be run on the server. For example, your app may be designed in a
The Project Wizard tends to set up applications in a virtual directory, but you can easily move the application to the root if you choose. You can run applications either out of the virtual or the root if you keep to strict relative pathing for images and other related file! Don't hardcode paths or your app will not be portable!
For application files again copy all files that are related to your project including the executable and data files. In addition copy the following:
This directory needs to be accessible to the SYSTEM account (or whatever account your Web Server is running under) with full access.
wc.dll?_maintain~UpdateExe
This wizard is responsible for configuring Web Connection applications online. Typically you'll run this Wizard after you've created an application locally and now need to move it to a server. This Wizard allows you to set up virtual directories, scriptmaps and configure and synch the Web Connection INI files and register COM servers.
This Wizard is selective and allows partial operations to be performed. For example, you can only create a scriptmap or only create a virtual directory, or you can do both. In other words, this Wizard is very versatile and can be used for many common Web server and registration tasks, which is especially useful when installing Web application on a live server or passing on steps to perform by an ISP.
Note that the configuration Wizard will not copy any files from your client to the server - it is purely a server configuration utility that must be physically run on the machine to be configured. This means you need physical access to the machine in question or some mechanism like pcAnywhere to run it.
If you're installing Web Connection for the first time and you will always run out of the root directory you will probably want to create a wconnect directory to hold the wc.dll and config files.
The configuration options on this page tell where to look for the server's INI file to get its settings (in this case WebDemo.ini) and pulls those values out if found. These values can be reset to new ones and overwritten. The final values are then synched in both the WebDemo.ini and wc.ini files.
Specify the name of the script map (this is a file extension so keep it to 2-4 characters - no period). Then point it to the Web Connection dll (wc.dll) of the application that this process class will be hooked to. If you were copying the DLL in the second step you will get a warning that the file doesn't exist which is OK because it will be copied when you finish.
You can also specify whether the script maps are local to the virtual directory or global to the Web site. It's recommended you create local scriptmaps to avoid confusion over which DLL is handling requests at the server level.
Server Exe
Pick the EXE file that you want to register. This file will be registered by running WebDemo /regserver to register the COM object.
ProgID
The progid of the server such as WebDemo.WebDemoServer. Note: No checks are made that this is correct, so make sure you know what the server's ProgID is. You can check the project settings. Typically the progid is the name of the project, dot, name of the class. If you let WC generate the project it'll be the project name, dot, project name + Server. Hence, WebDemo.exe results in WebDemo.WebDemoServer.
Server Impersonation
This option specifies the user account and password that your COM server will run under. This username can be one of the fixed Windows accounts like INTERACTIVE USER, SYSTEM, NETWORK SERVICE which require no passwords, or a specific Windows Account that exists on the machine. If you specify a user account you also have to specify the password.
This setting is equivalent to the DCOMCNFG Impersonation setting.
DCOM Launch Permissions
This option configures the DCOM Launch and Access permissions for your COM object. These settings add users to the permission list of the server so that applications and users can launch your COM object. Starting with Web Connection 5.0 typically you only need to set the System or NETWORK SERVICE account (depending on which account your Web Server or Application Pool is running under).
Web Connection by default adds these accounts to the list:
SYSTEM
NETWORK SERVICE ( IIS 6 only)
This setting is equivalent to the DCOMCNFG Default Launch and Access and Computer Launch and Access rights (if Add to Machine is checked).
Note:
DCOMPermissions.exe in your .\TOOLS directory is required in order to set the various DCOM settings automatically from the Wizard. Make sure you copy this file to your installation either in the .\TOOLS directory or in the same path as the CONSOLE.EXE file.
wc.ini Configuration Note:
This Wizard does not add the ProgId to your server wc.ini file if you are not copying a new wc.dll to your project. In other words - it assume your wc.ini file is already configured unless you are creating a new one. Therefore make sure that when you deploy your Web Connection DLL/INI that the ProgID matches:
... [Automation Servers] ;*** Severloading - 0 - Normal 1 - Round Robin ServerLoading=1 ;*** KeepAlive 0 - Normal 1 - Force extra COM reference to keep alive KeepAlive=1 Server1=webDemo.webDemoServer Server2=webDemo.webDemoServer ;Server3=webDemo.webDemoServer ...
Of course you can also manually configure your server and this topic shows you how to manually configure an IIS Web server. This topic should be followed up by:
In IIS to create a virtual directory:
Once you've done this you should see a dialog like this:

To set up the scriptmap:

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:
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!
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.
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.
o=CREATE("WebDemo.WebDemoServer")
? o.ProcessHit("query_string=wwMaint~FastHit")
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.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.
To do this you use the DCOMCNFG utility (part of Component Services in Windows XP/2003 Server and later):

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.
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.
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.
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.
Non Default Configurations 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 ServersFind 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.
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.
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.
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 "DCOM"
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" *** Add Launch and Access Permissions CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "SYSTEM" *** These two are not really required but a good idea for dev environments CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "Interactive" CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "Administrators" *** If you need to add a specific account CONSOLE "DCOMPERMISSION" "webDemo.WebDemoServer" "rstrahl","supersecretpassword"
From the Command window:
etc.DO CONSOLE WITH "DCOM","webDemo.WebDemoServer","IUSR_RASNOTEBOOK" DO CONSOLE WITH "DCOM","webDemo.WebDemoServer","Administrators"
Using pure code
This maybe useful if you want to build your own installer:
DO WCONNECT *** Set Impersonation User DCOMCnfgServer("wcDemo.wcDemoServer","Interactive") && Interactive User loAPI = CREATE("wwAPI") lcMachineName = loAPI.GetComputerName() *** 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!
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).
[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.
A recommended starting point for instances is 2 instances per processor. If you have light load operations
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.
However, if you want to manually configure your file based server after you've copied all files to the server here's how you do it.
Overview
Assuming you have copied your application to the Web server and you want to manually configure the server for File Based operation you have to configure the Web Connection application INI files so that the server and the wc.ini file can communicate with each other.
When working in Filebased mode the key thing is to make sure that your applications INI file (YourApp.ini or wcdemo.ini) is synched up properly with the Web Connection ISAPI INI file (wc.ini). Both need to point to the same directories for the temporary files so that they can communicate and the permissions on these directories need to be right.
Changing the your FoxPro server's settings
Your FoxPro Web Connection Server uses an INI file with the same name as the project to hold a number of startup parameters. The easiest way to change the most common settings is to start the server and use the Status form.
To make changes to the application's INI file simply change the value on the Status form and click the Save Server Settings button. When you exist the form these settings should be live. These settings are written into your application's ini file (<yourApp>.ini or wcDemo.ini for the demo app). You can also set these settings manually in the INI file of course.
The key settings for file based communication are:
[Main] Tempfilepath=d:\temp\wc\ Template=WC_
Changing the wc.ini settings
The Web Connection ISAPI INI file (wc.ini) contain configuration settings that tell the Web Connection web interface how to handle requests. This drives the C++ code and is separate from the INI settings above.
To make changes to the Web Connection ISAPI INI file find wc.ini in your Web directory or the bin directory of your Web application (ie. \inetpub\wwwroot\webdemo\bin\wc.ini). Open the file with a text editor or the Visual FoxPro editor.
[wwcgi] Path=d:\temp\wc\ Template=wc_
You'll want to change the Path and Template keys to match the value from your FoxPro server's INI file mentioned above.
Setting Permissions on the Temp folder
You need to make sure that SYSTEM, the Internet Guest Account (IUSR_<machinename> or whatever you have configured in IIS as the Anonymous User) and Administrators have FULL rights in the temp directory used in the entries above.
Starting up and checking settings
Once this is done you should be able to start up your Web Connection Server from Visual FoxPro or as an EXE. Try a request - it should work fine from here.

To trouble shoot a file based installation please check out the Troubleshooting a Filebase Server Installation topic.
This process can take many forms and there really are no hard and fast rules. Copying files tends to be a one time task and so it doesn't necessarily need to be an automated process.
However, it might be useful to organize your applications in a certain way to facilitate this copying process by specifically creating an application hierarchy for deployment that reflects the live environment so that you can copy the files from staging/development environment easily to the server.
The following is just a file and folder arrangement deployment suggestion, but it's one that's served me particularily well in the course of many installations.
It's helpful if your development setup matches the deployment setup, but that's not strictly necessary. Either way I'd recommend the intermediate step of creating a deployment installation and testing that installation before sending files to the server. The reason for this is simple - dev installs tend to include all source files so even if something in your project file is missing and not getting compiled into a final EXE it may still work because the source files are still available. A standalone EXE file may not have this luxury and fail unceremoniously.
Further I recommend using a deployment hierarchy of folders that include both the Application and data files as well as the Web specific file under a common non-IIS rooted directory. The folder structure for this arrangement then looks something like this:
AppRoot ApplicationFiles (EXE,Ini files, Web Connection Tools/html/Scripts/Template folders) Web (the Web Virtual directory where WCSX etc. scripts and templates live) Data (Optional data directory if you're using VFP data)
Note that in this scenario the web folder is NOT underneath the actual Web root (ie. c:\inetpub\wwwroot) which tends to be the default for the Wizard setups (because that's 'standard' place to put sites) - AppRoot can be any arbitrary folder. But using a non wwwroot based folder works perfectly fine for Web paths although it's crucial that permissions are set appropriately to allow the IIS anonymous user explicit Read/Execute access - this user by default exists only under wwwroot, but not under an arbitrary path.
The data path is optional - you can also stick data below your application folder, or in some situations your data may be in different paths on the machine or on the network depending on your security policy.
One advantage of the above layout though is that you have a single directory structure that can be sent to the server via FTP in one shot instead of having to pick files out of multiple paths scattered across the machine.
The following need to be moved to the server:
YourApplication.exe
YourApplication.ini
wwIPStuff.dll
zlib.dll
wwImaging.dll (required only if you use the imaging function in wwAPI)msvcr71.dll (for Apache only. should be copied into the System directory if it doesn't exist)
Console.exe
.\SCRIPTS
.\TEMPLATES
.\TOOLS\DComPersmissions.exe (can also go into the main directory)
In addition the Web Folder should include a BIN directory that holds the application's Web script engine.
If you're using the Web Connection module instead of the above files you should have:
wc.ini and web.config hold the configuration for the respective script engines and may need some custom configuration settings to reflect the live development environment. Specifically the temp file path and template need to be set and matched to the same setting.
Here's an example script that demonstrates a typical installation:
DO WCONNECT SET CLASSLIB TO WEBSERVER ADDITIVE lcApplication = "MyApplication" *** Hardcoded values - these would normally come *** from some sort of UI (popup a form?) *** Deployment Path lcWebPath = LOWER(FULLPATH("..\web\")) lcServerType = "IIS6" *** Name of the virtual Web directory for IIS lcVirtual = lcApplication lcServerExe = lcApplication + ".exe" lcTempPath = ADDBS(SYS(2023)) + "wc" **** COM Configuration lcProgId = lcApplication + "." + lcApplication + "Server" lcDCOMUserName = "Interactive User" lcDCOMPassword = "" && Fill in if you're using a real account *** End stock parameters *** Prompt for a few of the main parameters - ideally this should be a form to *** prompt for all the inputs lcServerName = "LOCALHOST" lcServerName = InputForm(lcServerName,"The local IP Address or domain of the server to configure","IIS Configuration - Server Address",,,"") IF EMPTY(lcServerName) return ENDIF lcServerType = InputForm(lcServerType,"IIS Version (IIS5, IIS6, IIS7)","IIS Configuration - IIS Server Type",,,"") IF EMPTY(lcServerType) return ENDIF lcWebPath = InputForm(lcWebPath,"Location of the Web Directory","IIS Configuration - Web Directory",,,"") IF EMPTY(lcWebPath) return ENDIF *** Create Virtual Directory oIIS = CREATEOBJECT("wwWebServer") oIIS.cServerType = lcServerType oIIS.cIISVirtualPath = "IIS://" + lcServerName + "/W3SVC/1/ROOT" && IIS Schema path oIIS.cApplicationPool = "West Wind Web Connection" IF ISNULL(GETOBJECT(oIIS.cIIsVirtualPath)) showStatus( "Unable to connect to IIS Administration COM object." ) return ENDIF showStatus("creating virtual directory") IF !oIIS.CreateVirtual(lcVirtual,lcWebPath) showStatus("Unable to create virtual directory") RETURN ENDIF *** Do some custom work on the new virtual *** Turn off Anonymous Permissions to FORCE LOGINS for EVERY REQUEST * loVirtual = GETOBJECT(oIIs.cIISVirtualPath + "/" + lcVirtual) * loVirtual.AuthAnonymous = .F. * loVirtual.SetInfo() *** Assume wc.dll lives in BIN directory lcScriptDLL = lcWebPath + 'bin\wc.dll' showStatus("creating script maps") lcIISVirtual = oIIS.cIISVirtualPath + "/" + lcVirtual *** Create script maps to the DLL oIIS.CreateScriptMap('wc',lcScriptDll, lcIISVirtual) oIIS.CreateScriptMap('wcsx',lcScriptDll, lcIISVirtual) oIIS.CreateScriptMap('wwsoap',lcScriptDll, lcIISVirtual) oIIS.CreateScriptMap('aspx',lcScriptDll, lcIISVirtual) showStatus("registering ISAPI dll in IIS") *** In IIS6 and later we have to register any DLLs with IIS IF LOWER(lcServerType) = "iis" AND LOWER(lcServerType) > "iis5" *** Add the DLL as a registered loIIS = CREATEOBJECT("wwIISAdmin") loIIS.cPath = "IIS://" + lcServerName + "/W3SVC" loIIS.AddRegisteredExtension(lcScriptDll,"West Wind Web Connection") loIIS = .f. ENDIF *** Create Temp Directory IF !ISDIR(lcTempPath) MD (lcTempPath) ENDIF *** Set permissions for IUSR_ Virtual loVirtual = GETOBJECT(oIIS.cIISVirtualPath) lcAnonymousUserName = loVirtual.AnonymousUserName loVirtual = .f. *!* *** Set access on the Web directory IF !EMPTY(lcWebPath) *** Read writes - wwUtils.SetAcl() llResult = SetAcl(lcWebPath,lcAnonymousUserName,"R",.t.) ENDIF *** Not required for Web Connection 5.x - wc.dll runs as SYSTEM * IF lcTempPath * *** Full rights in the temp directory * llResult = SetAcl(lcTempPath,lcAnonymousUserName,"F",.t.) * ENDIF showStatus("Register Com object") *** Register COM object and configure DCOM programmatically IF !EMPTY(lcProgId) wait window "Registering COM server" nowait lcCommand = "run " + lcServerExe + " /regserver" &lcCommand IF ISWinNT() IF !EMPTY(lcDCOMPassword) AND !FILE("DCOMPermissions.exe") MESSAGEBOX("DCOMPermissions.exe file is missing" + CHR(13) +; "Can't configure DCOM settings. Please configure manually.",48,"DCOM Settings") ELSE DO DCOMCNFGServer WITH lcProgId, lcDCOMUserName, lcDCOMPassword IF FILE("DCOMPermissions.exe") loAPI = CREATE("wwAPI") lcMachineName = loAPI.GetComputerName() DCOMLaunchPermissions(lcProgId,"Administrators") DCOMLaunchPermissions(lcProgId,"SYSTEM") DCOMLaunchPermissions(lcProgId,"INTERACTIVE") ENDIF ENDIF ENDIF ENDIF FUNCTION showStatus(lcMessage) WAIT WINDOW NOWAIT (lcMessage) ENDFUNC
This script is not generic obviously, but it can be customized quite easily in a few places for most configurations. You might want to add or remove some script maps (like ASPX which was used for this particular project) or you might need additional settings applied say to the virtual directory. Note that the code even does some custom ADSI configuration for setting security - in this case it's removing Anonymous user access from the app so that every user is forced to log in with Windows credentials.
The beauty of this sort of script is that once you have your configuration set up it's very easy to run it for a first time config or even to reconfigure if something should get accidentally removed.
If you want to deploy this you can either choose to build an EXE out of this small program by adding to a project and compiling into an EXE, or maybe even easier by adding it to your main server EXE itself with code like the following in the startup program (like wcDemoMain.prg):
************************************************************************ * MyApplicationMain ****************************** *** Created: 06.05.2008 *** Function: Web Connection Mainline program. Responsible for setting *** up the Web Connection Server and get it ready to *** receive requests in file messaging mode. ************************************************************************ LPARAMETERS lcAction IF !EMPTY(lcAction) IF UPPER(lcAction) == "CONFIG" DO configurationScript RETURN ENDIF ENDIF *** This is the file based start up code that gets *** the server form up and running #INCLUDE WCONNECT.H …
With this code the configuration script is now part of the server and you can simply do:
YourServer.exe Config
To run the configuration code. Simple and self contained and makes the configuration script available along with your EXE always.
AppRoot ApplicationFiles (EXE,Ini files, Web Connection Tools/html/Scripts/Template folders) Web (the Web Virtual directory where WCSX etc. scripts and templates live) Data (Optional data directory if you're using VFP data)
Note that in this scenario the web folder is NOT underneath the actual Web root (ie. c:\inetpub\wwwroot), but this works perfectly fine as long as the path is configured properly and permissions are set appropriately specifically for the IIS anonymous user (ie. IIS_YourMachine) to have read/execute access. The configuration script above handles this automatically by looking up the Anonymous account and setting permissions on the Web folder for this account.
For a more elaborate example of a front end you can take a look at the wwAppWizard class (especially the Configure Server method) and the ConfigureServer class in wcSetup.vcx. The source code for these classes is provided and you can build your own wizards based on them if you choose. Or you can build a much simpler form interface to customize with just the 4 or 5 configurable options to present to the user. In your own applications most options other than the install path are probably fixed so the user interface can be pretty simple for a front end.
Note that source code for the Setup, New Project and Configuration Wizards is also available - you can customize those Wizards with custom logos and customized code. The actual configuration code resides in wwAppWizard and you can override any of the individual methods as you see fit to customize setup behaviors.
Symptom: I'm trying to run Web Connection as a Service or at least run it so that no user needs to be logged on.
One topic that frequently comes up is how to set up Web Connection so that servers automatically start when the system boots up. Most people want WC to run as a service as a result of that. While it is possible to run WC as a service (using the NT ResKit's SvrAny program) I don't recommend this operation because the server cannot be controlled using the Web Connection server management features.
However, there are other more efficient ways to accomplish this task. Depending on whether you run COM or File based there are several mechanisms available:
Com Messaging
When running COM, Web Connection brings up Automation servers automatically when a link that requires a WC server is hit. You can even have Web Connection servers autoamtically load before anyone is logged onto the system by not using the Interactive account for Impersonation of the COM server. This is done using the Windows DCOMCnfg (part of Component Services) utility.
If you're always logged on under NT
If you're logged on under NT you should configure your Automation server to the Impersonate the Interactive User using the DCOMCnfg options (as described in OLE Automation Setup). Using this account allows the best operation of WC Automation servers that live visibly on the NT Desktop.AutoLogon to NT/2000/.Net Servers
A simple way to allow proper operation of WC is to use the above settings and force NT to automatically log in at boot up.Web Connection provides a utility in the via the Web Connection menu under Tools to create an AutoLogon entry in the registry for you or you can use the Management Console with the following code:
DO Console WITH "AUTOLOGON"To manually configure this option in the registry set the following registry keys:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
AutoAdminLogon REG_SZ 1 - AutoLogon 0 - Manual Logon DefaultPassword REG_SZ The accout password DefaultUsername REG_SZ The account nameRunning without an NT Logon
COM servers can run without having an NT logon. The default configuration is to run under Interactive which logs on to the local Console. However, you can configure your server very simply to either use the calling processes security context or by configuring a specific acccount which allows running without any login. The account you choose should have sufficient rights to access all resource your application might require.The easiest is to simply use pass through security from the calling process, which typically will be the IIS worker process or Application Pool (w3wp.exe). It's optimal for Web Connection to run using the local system account and if this account is used it's the best choice for running without a logon. One limitation of the System account is that it has no network rights so if you need to access files on network shares or possibly connect to a remote SQL server system may not work.
You can also set up your server to run under a specific account in which case DCOM will impersontate that specific account on every request. To do this go into DCOMCNFG and find your COM server in the list of servers and assign the specific user and password.
This user should have rights to access your data directories, TEMP and any remote SQL or network connections that your app may need (since this user is tied to your server it's OK to use an Admin account here!). Select your specific server within the DCOMCnfg and click on the Identity tab. Choose This User: and enter a valid account and password. I recommend you use an Admin account so you have full access to the machine/network via the Automation server.
Test the server with your custom DCOM account with a logon first to make sure it works! The server will not be visible because it now runs as part of the IIS Service context. However, it should still serve requests just fine. Since the server is invisible you might also want to adjust the startup INI settings to surpress the server form (ShowServerForm=Off) - no need for this overhead. Once you're sure the server runs with this account, restart the Web Service (to unload everything) and log off the machine. The server should continue to work at this point. If these settings work your application is ready for running as part of the IIS Service and acts like a system service.
Note: When your server is configured as using a specific account or Launching User the Web Connection server runs invisibly regardless of the Interact with Desktop flag of the Web service.
File Based
When running file based servers do not start up automatically as the Web Connection servers are standalone Visual FoxPro applications.
AutoLogon to NT and Startup Group entries
The easiest way to force WC servers to start up is to use Autologon (as described above) and server entries in the startup group. When the machine boots the startup group fires off servers automatically.The StartFileInstances flag in wc.ini
You can automatically start Web Connection server instances the first time a call to wc.dll is made by specifying the following two keys in wc.ini:ExeFile=c:\wwapps\wc2\wcdemo.exe FileStartInstances=2Servers started in this fashion can be auto-started before NT logon, but the servers will run invisibly. When you do log on the servers will become visible.
The value in the Current Login setting is the user account that the Web Server is running. Usually this account will be your SYSTEM account, but it can also be NETWORK SERVICE, or any account you configured for the service or IIS 6 Application Pool.
The main part of the form is made up of the process display which shows the current request running and the time that it took to run it.
The Status button on this form takes you to the Server Status form that shows the server's current operational parameters and allows you to adjust these settings and save them for startup.
Here's what the various fields mean:
Startup Path
The startup path shows the location that the server is currently running from. This path is set the first time the server is run based on the server's physical disk location and then stored in the registry. Everytime the server starts this value is read from the registry and the server path (SET DEFAULT/CD) is then changed to the specified directory.
Typically this path will always match the server's physical location on the disk, but in some special situations you'll want to override this path to a different location. For example, when running a file based Web Connection server on another machine it makes sense to change the path to the remote machine so that all the configuration and data files can be found with relative paths.
In any case you can change this setting to re-write the value into the registry.
Maps to wwServer::cTempFilePath
Temp Files, Timer Interval and File Template - File based operation only
These settings are specific to operating Web Connection in file based mode and determine where and how the file messages are processed by WWWC. The temp file path shows the path where the server expects request files to coming in from the Web server. This setting should match what the Path= setting says in wc.ini. The timer interval determines how often the file based server polls for new request files. The shorter the interval the faster the turnaround. The default is 200 milliseconds. It's not recommended that you set this value smaller than 75 unless your server is super busy all the time. The Template identifies what type of files the server is polling for in the temp directory. Again this value must match the active wc.ini Template setting.
Show Status
This flag determines whether the server window displays each request in its window.
Maps to wwServer::lShowStatus
Log to File
Determines whether Web Conection's request logging is turned on. By default Web Connection logs every request to a DBF file, RequestLog.dbf by default. This flag enables or disables this logging.
Maps to: wwServer::lLogToFile
Script Mode
The script mode determines how Web Connection interprets WCS script files. You can choose between interpreted and compiled operation. Scripts can be compiled on the Admin page.
Maps to: wwServer::nScriptMode
To do so use the options on the bottom of the status form:
The Save Request Files checkbox causes every request to save its inputs and outputs to a static text file in your temp directory. The files are static and are called TEMP.HTM and TEMP.INI. This feature is meant as a debugging mechanism so it's not advisable to have this option enabled in a production environment.
Once the checkbox is set run a request. Come back to this form and click on the Display Request button. The resulting popup allows you to view the full HTTP output from the last request including the HTTP header, a parsed version of the the Request input, which displays form variables and Server Variables in a key value display, and a raw version of the Request input which shows the raw request data in its URLEncoded format.
Viewing the request data provides extremely useful debug information that tells you exactly what a client request posted to the server. This is very useful for debugging HTML form problems as well as things like Cookie and Authentication issues where logins apparently fail. This data is provided straight from the Web server so if it's not here, it didn't get sent!
Use to make sure your app is getting what you think it is!
The wc.ini and application INI files can be configured through the server's status form. The application settings can be interactively edited on the Server Status form, while the wc.ini settings are always set in the INI file directly.
The wc.ini file contains settings that determine the operation of the Web Connection ISAPI interface. The values set in the INI file affect the operation of the low level interface that runs inside of IIS under the security context configured for IIS or the specific IIS Application Pool that hosts the ISAPI DLL.
NOTE:
Note the wc.ini file applies to operation with the ISAPI extension (wc.dll). When operating with the Web Connection IIS Module the configuration file settings are stored in web.config in the root of your Web application.
This file contains several runtime options that are used by the ISAPI DLL to determine how to operate. A typical wc.ini file looks like this:
[wwcgi] ;*** THIS DIRECTORY MUST HAVE READ AND WRITE ACCESS FOR THE Path=c:\TEMP\ ;*** Time to allow request to finish ;*** Process will be terminated after number of secs ;*** specified here. REQUIRED Timeout=50 ;*** Specify how often wc.dll polls for 'completion' message ;*** Specify in milliseconds. REQUIRED FOR FILE BASED PollTime=100 ;*** Max size allowed for the POST buffer. If the post buffer is bigger *** than this value in bytes the data is not posted. 0 - means no checks. PostBufferLimit=0 ;*** Message File Template (1st 3 letters) ;*** Default is "wc_" Only needed if using a different template Template=wc_ ;*** Messaging Mechanism of the DLL: REQUIRED ;*** File - Original Web Connection Logic of ; file based messaging ;*** Automation - Use OLE Automation Server Interface ;*** Interactive - Call up the VFP development environment via Automation Mechanism=File ; PostMethod - URLEncoded or INI - Match POSTMETHOD in WCONNECT.H PostMethod=UrlEncoded ; Determines whether Web Connection DLL uses Impersonation (1) of the ; Web user account (IUSR_ or logged in user) or whether it uses the ; underlying IIS account (0)(SYSTEM/NETWORK SERVICE or Application Pool ; configured value. ; 0 - No Impersonation (default) 1 - Impersonation Impersonation=0 ;*** Account for Admin tasks REQUIRED FOR ADMIN TASKS ;*** NT User Account - The specified user must log in ;*** Any - Any logged in user ;*** - Blank - no Authentication AdminAccount=gonzo,ricks,maxhead ;Admin Page that is used for Backlinks from various internal pages ;Use a full server relative Web path! AdminPage=/wconnect/Admin.asp ;*** You can update an EXE on the fly from the UpdateFile ;*** With File base messaging you can also use StartEXE to start the ;*** ExeFile running ExeFile=d:\wwapps\wconnect\wcCOMdemo.exe UpdateFile=c:\temp\wcComdemo.exe FileStartInstances=0 [Automation Servers] ;*** Severloading - 0 - Normal 1 - Round Robin ServerLoading=1 ;*** KeepAlive 0 - Normal 1 - Force extra COM reference to keep alive KeepAlive=1 ;*** Force users to see message while servers are loading ;*** Set to one if you have problems getting servers loaded ;*** in high volume environments to reduce thread backups COMLoadLockout=0 ServerObject=0 Server1=wcDemo.wcDemoServer Server2=wcDemo.wcDemoServer ;Server3=wcDemo.wcDemoServer,WestWindServer2 ;Server4=wcDemo.wcDemoServer,WestWindServer2 [Extra Server Variables] Var1=LOCAL_ADDR Var2=APPL_MD_PATH Var3=HTTP_CACHE_CONTROL [HTML PAGES] ;*** Use these to override DLL messages DLLStatusHeaderText= Busy= NoOutput= OleError= Timeout= ;Maintenance=c:\westwind\wconnect\dllerror.htm Exception= Maintenance= NoLoad=
Busy= NoOutput= OleError= Execption= Maintenance= NoLoad= Timeout= PostBufferSize=
Here's a description of what these values do:
| Key | Description |
|
Path |
Determines where the DLL sends the server request file that contains the content of a particular request. Typically this will be your system Temp directory |
|
Timeout |
Determines how long a request can take before it is timed out and an error page is returned to the Web server. If you plan on requests taking more than 60 seconds each youll need to bump this value up. Default: 60 (seconds) |
|
PollTime |
Applies to file based only and determines how often the DLL polls for a return result. Default: 200 (millisecs) |
|
Template |
Applies to file based only and determines the 3 letter prefix that is used for the messaging files. Default: WC_ |
|
Mechanism |
Determines whether file based or Automation based messaging is used. Values are: Automation or File |
|
PostMethod |
Determines how the Request data is encoded. Older versions of Web Connection used an INI file newer version pass URLEncoded strings. If using the default of URLEncoded wconnect.h must have #DEFINE POSTDATA .T. Values are: URLEncoded or INI. |
| Impersonation | Determines under which user context wc.dll executes internal ISAPI requests.
0 (default) 1 |
|
AdminAccount |
Allows setting of the Administrative account that is allowed to access the DLLs internal Maintenance functions that can start and stop servers. If an account is specified only that account will be allowed access. If not logged into the Web server a login will be prompted. Values: AccountName The account to check for |
|
AdminPage |
Full path to the admin page you use. This is used to provide a back link from the various Maintenance functions built into the DLL. Example: c:\http\wconnect\admin.asp. |
|
ExeFile UpdateFile |
These two entries allow you to update EXE files online while the server is running. You can set up the EXE file of the server and provide a name for another file that serves as an update file. The Maintain?UpdateExe allows you to upload a file to a server and hot swap server EXEs without stopping the Web service. For file based messaging you need to make sure all servers are shut down first or else the update will fail. You can also use StartEXE to restart a stalled server or to restart after an update. ExeFile=c:\wwapps\wwdemo\wwdemoole.exe UpdateFile=c:\ftp\uploads\wwdemoole.exe |
|
FileStartInstances |
This flag allows you to automatically launch Web Connection servers when the Web Connection DLL is first loaded. This key uses the value in ExeFile to determine which EXE to launch. Make sure you test operation of this feature first by using the wc.dll/maintain?StartExe function to load your EXE, since this function returns error information. If FileStartInstances cannot load your servers no indication is given of the failure. |
|
[Automation Servers] |
This section of the INI file determines which servers are loaded on requests. Note the ability to access remote servers with the last example. [Automation Servers]
Serverloading=0
|
|
ServerLoading |
Used only in the Automation Server section this option determines how requests cycle through the loaded servers. 0 -Load Based |
|
KeepAlive |
This flag allows getting around a DCOM bug that causes COM objects loaded by IIS threads to unload after 8 minutes of idle time. KeepAlive forces an extra reference on the server making COM keep the server locked and making it not unloadable. 0 Normal 1 Keep Alive Keeps an extra COM reference to force servers to stay alive at all times. Servers unload only when IIS unloads or when you use Web Connection's own unload links. |
|
[Extra Server Variables] |
Use this section to add additional HTTP Server variables that IIS provides to your incoming Request object. Web Connection provides the most common varialbe - this option allows you to retrieve any additional ones that aren't natively provided. Use Var1, Var2, Var3 etc. keys to specify each of the server vars to add. |
Web Connection provides most of IIS Server Variables by default. However it selectively pulls these variables to optimize performance so some server variables may not be available via the native Request.ServerVariables() method. You can easily see what server variables are pulled on each request by using the Show Status button after a request has been fired with Save Request Data checkbox checked. Look Request Data.
However, Web Servers evolve and some servers other than IIS might expose additional server variables that don't get pulled by default. For this instance you can override the default behavior to allow adding any custom HTTP Servervariables explicitly by specifying the Server variable names in the [Extra Server Variables] section of the wc.ini file. To add any server variables not provided use the following syntax:
[Extra Server Variables] Var1=LOCAL_ADDR Var2=APPL_MD_PATH
To find out about the server variables IIS exposes see MSDN online.
The Web Connection ISAPI extension can throw several errors internally. By default these errors generate error messages that are displayed as HTML generated to a simple template inside of the DLL. Since these errors never hit the Web Connection Visual FoxPro server, this means you can't change the error message directly. In some instances this may not be appropriate. While errors are rare and usually point to a problem in the Visual FoxPro server code, it's sometimes necessary to provide an error message that is suitable for end users rather than the technical message that the DLL pops up. So, to do this you can provide an override form for each error message via settings inside of wc.ini. The following entries and error messages are available for customization: Ini Entry [HTML PAGES] Conditions:
[HTML PAGES] DLLStatusHeaderText=Custom Web Connection Status DLL Text Exception=C:\westwind\wconnect\error.htm Maintenance=C:\westwind\wconnect\error.htm NoLoad=C:\westwind\wconnect\error.htm Busy=C:\westwind\wconnect\error.htm
Timeout= PostBufferSize= TransmitFileFailure=The special DLLStatusHeaderText key allows you to override the DLL Status page header. The default value you see is Web Connection DLL Status. You can override this header with your own to remove references to Web Connection.
Displaying Error information in custom pages
This mechanism is very low tech, but you can also embed two special %s keys into the page to match the error message that the Web Connection request creates. Embed the %s string into the page and the first encountered will expand to the error header, the second to the error message.
Note that you can hide the first parameter with something like this:
The server settings are required while the process module settings are optional and can be defined by you as you need them. By default Web Connection manages the INI file settings through a custom implementation of the wwServerConfig class (defined in wwServer.prg and subclasses from the wwConfig class) which dynamically manages the settings via an object that persists its properties into the INI file.
The application INI file has the same name as the project. So the demo application is wcDemo and the ini file is wcDemo.ini. The Ini file looks like this:
[Main] tempfilepath=c:\temp\ template=wc_ logtofile=On saverequestfiles=Off showrequestdata=Off showserverform=On showstatus=On usemts=Off scriptmode=3 timerinterval=200 adminemail=rstrahl@west-wind.com adminmailserver=mail.gorge.net adminsenderroremail=Off [wwdemo] datapath=d:\wwapps\wc3\wwDemo\ htmlpagepath=d:\westwind\wconnect\ [http] datapath=d:\wwapps\wc3\wwDemo\ htmlpagepath=d:\westwind\wconnect\ serverport=80 adminaccount=rstrahl
The [Main] section contains server settings. Any other sections like [wwdemo] and [http] map to process classes that you implement. You can add any custom values to these INI files as you see fit. Please see the wwServerConfig object for more detailed information on the individual keys.
Skip to the bottom of wcDemoMain.prg to find this code:
DEFINE CLASS wcDemoConfig as wwServerConfig
owwDemo = .NULL.
owwMaint = .NULL.
oWebHits = .NULL.
oHTTP = .NULL.
FUNCTION Init
THIS.owwDemo = CREATE("wwDemoConfig")
THIS.owwMaint = CREATE("wwDemoConfig")
THIS.oHTTP = CREATE("HTTPConfig")
THIS.oWebHits = CREATE("WebHitsConfig")
ENDFUNC
ENDDEFINE
DEFINE CLASS wwDemoConfig as RELATION
cHTMLPagePath = "d:\westwind\wconnect\"
cDATAPath = "d:\wwapps\wc3\wwDemo\"
ENDDEFINE
DEFINE CLASS httpConfig as RELATION
cHTMLPagePath = "d:\westwind\wconnect\"
cDATAPath = "d:\wwapps\wc3\wwDemo\"
cServerPort = "80"
cAdminAccount = "rstrahl"
ENDDEFINE
The main wcDemoConfig object is the 'server' config object which becomes accessible as Server.oConfig (it's based on wwServerConfig which you can find in wwServer.prg). It contains server start up settings like the temp path, templates, timeouts and so on that are a required part of the Web Connection server. You can add additional properties if you want them to be available on the server object.
If you change a value in the INI file, the value is read on server startup and the class value is changed to the INI file value - if the INI value doesn't exist the default property value is used.
Notice that each of the sub-process classes get a custom object that is attached to the main server config object. For example, oHTTP is simply a new object with properties that match your INI file settings you want to create. Every property you add becomes a key value.
To add any other sections simply create another class with the properties you want to use and the wwConfig class will take care of the rest.
Note that the New Project and New Process Wizards handle creating of the basic objects for you automatically. All you have to do is add your custom properties to persist in the INI file.
Important: All properties you create should be created with a type prefix like cServerPort, cDataPath, nSeconds. The prefix is dropped when written out to the INI file. If you omit the prefix you'll run into truncated values in the INI file - it'll still work, but it sure will look funny.
Tip:
DO NOT CHANGE SETTINGS IN THIS FILE! This file will be updated every time Web Connection is updated so any changes you make here will be overridden. Instead you can make changes in wconnect_override.h as described in the Customizing wconnect.h settings topic.
#DEFINE DEBUGMODE .T.
#DEFINE SERVER_IN_DESKTOP .F.
#DEFINE WWXML_USE_VFP_XMLTOCURSOR .F.
#DEFINE WWWC_FILTER_UNSAFECOMMANDS .F.
#DEFINE DEFAULT_HTTP_VERSION "1.0"
#DEFINE DEFAULT_CONTENTTYPE_HEADER ;
"HTTP/1.0 200 OK" + CR + ;
"Content-type: text/html" + CR#DEFINE MAX_STRINGSIZE 10000
#DEFINE WWC_SERVER wwServer #DEFINE WWC_SERVERFORM wwServerForm #DEFINE WWC_SERVERFORM_VFPFRAME wwServerFormVFPFrame #DEFINE WWC_PROCESS wwProcess #DEFINE WWC_WEBSERVICE wwWebService #DEFINE WWC_SESSION wwSession #DEFINE WWC_SQLSESSION wwSessionSQL #DEFINE WWC_REQUEST wwRequest #DEFINE WWC_REQUESTASP wwASPRequest #DEFINE WWC_RESPONSE wwResponse #DEFINE WWC_RESPONSEFILE wwResponseFile #DEFINE WWC_RESPONSESTRING wwResponseString #DEFINE WWC_RESPONSEASP wwASPResponse #DEFINE WWC_RESPONSEBEHAVIOR wwResponseFileBehavior #DEFINE WWC_HTTPHEADER wwHTTPHeader #DEFINE WWC_wwEval wwEval #DEFINE WWC_wwHTMLControl wwHTMLControl #DEFINE WWC_WWVFPSCRIPT wwVFPScript #DEFINE WWC_WWPDF wwPDF #DEFINE WWC_WWSOAP wwSOAP
#DEFINE WWC_LOAD_DYNAMICHTML_FORMRENDERING .T. #DEFINE WWC_LOAD_WWSESSION .T. #DEFINE WWC_LOAD_WWBANNER .T. #DEFINE WWC_LOAD_WWDBFPOPUP .T. #DEFINE WWC_LOAD_WWIPSTUFF .T. #DEFINE WWC_LOAD_WWVFPSCRIPT .T. #DEFINE WWC_LOAD_WWSQL .T. #DEFINE WWC_LOAD_WWPDF .T. #DEFINE WWC_LOAD_WWXML .T. && Don't change! Required! #DEFINE WWC_LOAD_WWMSMQ .F. #DEFINE WWC_LOAD_WWSOAP .T.
The remainder of settings in wconnect.h are system defines and values that are used internally in various classes.
Additional useful flags:
#DEFINE WWC_CACHE_TEMPLATES 0
Determines whether templates called with Response.ExpandTemplate() are cached in a table rather than being read from disk each time. If you have applications that use lots of templates this approach may provide a significant performance boost. Number specifies the number of seconds that a template is cached - 0 means that no caching occurs.
#DEFINE WWC_EXTENDED_LOGGING_FORMAT .F.
This option when set to .T. causes additional information to be logged into the Web Connection Request log. When set, the POST data and Browser string get logged in addition to the querystring, script, and client IP address. Turning this option on can quickly generate a very large log file so please use this option with caution and if you do use frequently clean out your log!
#DEFINE MAX_TABLE_CELLS 15000
Determines the number of table cells that the wwShowCursor class can render in a single table before changing output format to a text based list. Since tables can get too large to comfortably render as tables this maximum can be applied.
wconnect.h includes a reference to an override header file that you can use for this purpose with the following line:
#IF FILE("WCONNECT_OVERRIDE.H")
#INCLUDE WCONNECT_OVERRIDE.H
#ENDIF
wconnect_override.h should then contain #UNDEFINE statements for all constants you want to change along with #DEFINE statements for the new values. You can do this as follows:
#UNDEFINE DEBUGMODE #DEFINE DEBUGMODE .F. #UNDEFINE MAX_TABLE_CELLS #DEFINE MAX_TABLE_CELLS 20000 #UNDEFINE WWC_CACHE_TEMPLATES #DEFINE WWC_CACHE_TEMPLATES 0 #UNDEFINE VISUALWEBBUILDER #DEFINE VISUALWEBBUILDER .F. #UNDEFINE WWC_USE_SQL_SYSTEMFILES #DEFINE WWC_USE_SQL_SYSTEMFILES .F. #UNDEFINE WWSTORE_USE_SQL_TABLES #DEFINE WWSTORE_USE_SQL_TABLES .F. #UNDEFINE WWMSGBOARD_USE_SQL_TABLES #DEFINE WWMSGBOARD_USE_SQL_TABLES .F.
When an upgrade rolls around Web Connection will overwrite your wconnect.h, but the settings in wconnect_override.h remain intact.
The admin page can be reached with http://localhost/wconnect/admin.asp and looks as follows:
Adminstrative links break down into two groups:
Note:
The admin page contains a process list componenent using the WMI (Windows Management Instrumentation) component that displays a list of processes that match the filters. This code runs in the ASP portion of the document and can be customized to include custom processes to view and kill if necessary. The default is inetinfo and anything wc*.*. In order to view this components output you have to be logged in (IUSR_ doesn't have rights to it) and you have to be running Windows 2000 or Windows NT 4.0 SP4 or later. For Windows 98 or NT pre SP4 you can download the WMI components from the Microsoft Web site. If the component is not available or the authentication is not in place the error handler skips over the display code and nothing displays. In order to set up authentication, set NTFS permissions on the ADMIN.ASP page for an admin account.
The Web Connection wc.dll provides a number of built in functions for managing Web Connection servers. These maintainence functions are available only through the Web interface of an application and follow a very specific format.
All of the maintainence requests are accessed by using a special syntax with the ISAPI DLL. For example to release all servers you would access:
http://localhost/wconnect/wc.dll?_Maintain~Release
You use _maintain to let the ISAPI DLL know that it's to expect a maintainence request. The second parameter then specify the operation to perform - in this case Release.
Security
Access to all maintainence functions of the DLL is controlled via Basic Authentication (on NT/2000 accounts) on the Web server. A special key in wc.ini AdminAccount determines which account has access to maintainence functions. This key can be blank to not check for Authentication, Any to allow any logged in account (ie. anything but the anonymous IUSR_ account) or a valid NT user account name. For more details see the wc.ini section under AdminAccount.
Maintenance DLL Status Page
To facilitate the process of the maintenance functions, a special link on the admin page called Show and Manage DLL settings allows access to most of the DLL maintenance functionality via an HTML interface. The page is accessed with wc.dll?_maintain~ShowStatus and looks like this:

This page shows the current status of most of Web Connection's settings that are loaded from the wc.ini file at startup. You can use the Re-read configuration link to reload the settings from the INI file. This link is extremely useful for debugging Web Connection problems as it shows you the real settings that the Web Connection ISAPI is running right now.
This page also allows you to switch between file based messaging and COM based messaging, put the server on temporary hold (Hold Requests) and lets you load and unload the currently running servers when running in COM mode. The COM server list shows the currently running servers and their status. Hits shows the cumulative number of hits against your Web Connection Server, Active requests shows the number of seconds the currently active request has been running if any (this will rarely show anything unless you have a long running request), and Cumulative shows the cumulative seconds that your server has spent processing requests since it was started.
The _maintain ISAPI DLL request parameters
The following table lists all of the maintainence features available inside of the ISAPI DLL. You access these by specifying wc.dll (or a script map thereof) and addressing it like this:
wc.dll?_maintain~MaintRequest
where MaintRequest is one of the parameters from the table below:
|
ISAPI Command |
What it does |
COM |
File |
|
ShowStatus |
Displays information of the current settings of the DLL. For Automation servers this display also shows which servers are loaded and if they are currently busy. This link summarizes the most important settings in wc.ini and you should use it to make sure you have all expected settings correctly set. |
u |
u |
|
ShowStatusXml |
Displays the same information that ShowStatus displays but in XML format for remote checks of status. |
u |
u |
|
Load |
Loads all the specified Automation servers into memory from the DLL startup INI file. |
u |
|
|
Release |
Releases all Automation servers from memory. |
u |
|
|
StartEXE |
Starts an EXE specified in ExeFile in the DLL Ini file for file based messaging. The EXE is started in the System context so it will run invisibly when started from a Service. You can make the session visible by allowing the service to 'Interact with Desktop' in the Service manager. Use this only if you've crashed the server, or if you've switched from Automation to File based and you need to get one server started to manage additionals. You can also use the FileStartInstances key in wc.ini to force instances to start up when the DLL first loads simulating behavior of an NT service and OLE Automation with file based operation. |
|
u |
|
UpdateExe |
Updates the EXE file as specified by the INI file EXEFile and UpdateFile keys. With Automation the process is automatic: Servers are unload, the Hold RequestFlag is set and the EXE file is copied. The servers are then reloaded. With file based messaging you are responsible for unloading all running sessions first using the Session links (see next section). Once unloaded the update operation is identical. |
u |
u |
|
MaintMode |
Releases all but one of the Automation servers from memory. This is very useful for doing maintainence tasks that require exclusive access to tables when running more than 1 server instance for a particular application. |
u |
|
|
HoldRequests |
Forces the DLL to return 'Please wait...' message page for all users and unloading all COM servers if running in COM mode, essentially locking down the Web Connection server except for users logged in under the AdminAccount list. This can be used to update files on the server including Automation Server executables. This flag is a toggle that switches between on/off modes. |
u |
u |
|
MaintHoldRequests |
Works just like HoldRequests except it also loads a single COM Server instance so you can perform maintenance operations using the Web Connection server. When through use HoldRequests to toggle the HoldRequest flag back to off. |
u |
|
|
RecoverDeadLock |
Manually overrides the HoldRequests flag in case you set it and can't access the maintainence page when not logged in. This setting also resets the spin and lock counts shown in the DLL Status page in the rare event that these value stay above 0 for extended periods. |
u |
|
|
ReadSetupIni |
Re-reads the settings from the DLL startup INI file. |
u |
u |
|
SetFileMechanism |
Switch the DLL from Automation to File based message processing. |
u |
|
|
SetAutoMechanism |
Switch the DLL from File based to Automation message processing. |
|
u |
|
KeepAlive |
This request fires all of the Automation servers currently loaded. You can use this link to keep alive servers from Web Monitor by hitting it every 2 minutes. IIS unloads low usage threads after approximately 8 minutes and this allows keeping servers running. Servers are hit only if idle for more than 1 minute. |
u |
|
Updating code online without shutting down the Web server is possible with Web Connection when operating under COM with the Web Connection Pool Manager. The idea is that you upload your new executable to the server into a temporary location and then use an update link to actually copy the new file over the existing version. It's not quite so easy however, as you have to make sure all other sessions of the EXE are terminated before updating the file. This is easy to do with COM operation, but quite messy and potentially risky with file based operation.
The first thing you have to do is set up the wc.ini keys EXEFile and UpdateExe. The EXEfile should point at your executable file, while the UpdateExe should point at the new EXE file that you will upload to the Web server. It's very important that the Admin account that you use when you click the link (and is set up as the AdminAccount key in wc.ini) has access rights to read the file from the source directory and write access in the target.
To actually update the files:
COM Messaging
With Automation the process is actually automated. Assuming you have the files in the correct location all you have to do is click Update Code on the maintainence page and all servers are shut down for you and the files copied. Once complete the servers are restarted for you. You use the UpdateExe and ExeFile keys in the wc.ini file to swap out files in real time.
File Based Messaging
File based is more difficult as the ISAPI DLL has no control over the server instances. Instead you have to first kill all server instances by using wc.dll?wwMaint~Sessions~KillUnconditional until ALL sessions have been killed from the server. You can then click the Update EXE link. Once the files have been updated you now have no sessions running. In order to start a session you have run the Emergency Restart Exe file link on the maintainence page. This will start up the EXE specified in the EXEFile key of wc.ini. Note that this server will run invisibly on the NT desktop – it will be visible only in task manager (or if you have your Web server set up in the Service Manager to 'Interact with Desktop').
http://localhost/yourVirtual/WebResourceUpdate.wc?wwMaint~WebResourceUpdate
In order for this to work however you have to ensure that the following directories exist in your Web Connection installation (whereever the the EXE lives):
This operation updates:
In addition you can set the following in WCONNECT_OVERRIDE.H:
#UNDEFINE WWC_EXTENDED_LOGGING_FORMAT #DEFINE WWC_EXTENDED_LOGGING_FORMAT .T.
To force Web Connection to use an extended logging format. In this mode it also logs:
Note that using the extended format collects significantly more data and should be used cautiously - primarily for debugging purposes if you have problems or need to track down a malicious client.
wc.dll?wwMaint~ShowLog
Note that you'll only see the last 400 records. This is done to keep the request short and not overload the browser's HTML table display. If you have the Office Web Components installed on the server Web Connection will also generate a chart of traffic over the last 25 hours.
You can override the number of records to show by providing a LogSize parameter:
wc.dll?wwMaint~ShowLog~&LogSize=1000
By default the log displays in normal, non-extended mode. To show extended log information including browser and POST data use:
wc.dll?wwMaint~ShowLog~&ExtendedLog=True&LogSize=500
wc.dll?wwMaint~LogSummary
You can also view a summary of hits tallied request. This works only for numbered parameters (wwDemo~TestPage for example). You can group by each parameter number. So, application would be 1, request would be 2 etc. Currently there's no support for scripts - script pages will not be counted.
wc.dll?wwMaint~ClearLog~NOBACKUP
In order to clear the log only one session can be running as exclusive access to the log file is required. When the log is cleared only the data up to the current day is cleared - today's data always stays in the file. When clearing the data in the log is appended to LOGBACK.DBF for archive purposes. Ideally, you want to run a daily log and keep the archive for reporting purposes. This file can get big, and clearing can get slow because of the APPENDs to the LOGBACK file. If you don't want a backup use the NOBACKUP parameter.
Running multiple sessions can provide the scalability needed to run simultaneous requests, but it also causes some maintenance headaches. If you're running multiple sessions it becomes crucial that you can shut down sessions so you can perform maintenance tasks that might require exclusive access to your data files. How often this occurs depends on your site, but if you are running a site that's running offline from another database application with data being shuffled back and forth maintenance tasks occur frequently.
Session management for Automation servers is handled via the DLL Maintain functions described in the previous section. For file based messaging the DLL has no control over the standalone VFP EXE files and thus can't manage them. The wwMaint module handles some of the chores by using the RUN and QUIT commands to manage running sessions using its Sessions method.
Note: In order to start a new session of Visual FoxPro development you need to set the following key in the wcmain.ini file in the Web Connection root:
[wwMaint]
RestartExePath=c:\vfp\vfp.exe -t wcmain.prg
or
; RestartExePath=c:\wconnect\wcdemo.exe
The URL syntax for the available functionality is:
wc.dll?wwMaint~Sessions~KILL
Kills a session that's running by executing a QUIT from the server that's hit.
wc.dll?wwMaint~Sessions~START
Starts a new session. Note that at least one session must already be running for this to work since Web Connection implements this mechanism. Web Connection actually issues a RUN command to start another session. If all sessions are dead you can use the next link to start a new instance.
wc.dll?_maintain~StartExe
This URL will restart a Web Connection server as a standalone EXE file from the ISAPI extension. The ISAPI extension reads the location of the EXE file from wc.ini in the EXEFILE key.
NOTE: the server will start invisibly (no UI). Make sure you test starting servers in this fashion. Note that servers started in this fashion act differently than servers started from the Desktop. Servers are started using the SYSTEM account so set your permissions accordingly.
Note:
File based server sessions are not recommended. If you need to manage multiple Web Connection instances it's highly recommended you use COM messaging, which allows full control over loading and unloading of servers including status information and crash recovery.
You can also use the Upload File: input box to upload with HTTP directly from this page. The File gets copied to the server based on the UpdateFile key in wc.ini. Another key ExeFile specifies the target file of a Code update.
When you click the button the Web Connection ISAPI DLL will try to delete the ExeFile first. This ensures that the file can be unloaded and is not running on the server. It then copies the UpdateFile to the ExeFile location. In COM mode, COM servers are unloaded before the delete and copy operation occurs. In file mode, no special action occurs - you're responsible for unloading servers on the Web Server using the Admin commands or other mechanism.
Warning:
This operation is based entirely on the keys defined in wc.ini. If you have either of these keys incorrectly set it's possible that a running file is deleted and not copied back. Make 100% sure you test this before making critical live site code updates!
wc.dll?wwMaint~ServerStatus
wc.dll?wwMaint~ShowStatus
These pages report settings for the server. The first requires IE 4.0 and allows editing the same server settings you can interactively change on the server's status form. The latter only displays stats about the running application.
Warning! It's highly recommended that you add Authentication to the requests discussed here or else risk the consequences of people messing with your site. If you check out the wwMaint.prg file Process method you'll find some commented out code that enables security based on a password defined in a #DEFINE that you set up. In addition it's a good idea to set security on the Maintain.htm page that contains all the links to these requests.
wc.dll?wwMaint~EditConfig
It's also possible to edit the Web Connection Configuration files remotely. This link displays a page with the server's config files for the DLL Ini file (wc.ini) or the Web Connection Server (wcMain.ini or whatever your main program is). The files are displayed in textboxes and can be edited and updated via a edit box and button.
Note: Updates work only if the Web Connection server resides on the same box as the Web Server. This request will not work if the INI files reside on remote machines due to the paths that are returned by the Web Server for the DLL and INI files. You can however modify the code in wwMaint.prg to hardcode the appropriate server path.
wc.dll?wwMaint~EditConfig~SaveDLLIni
wc.dll?wwMaint~EditConfig~SaveWCIni
If you're running COM/Automation you can use the [Automation Servers] section to add and remove servers from the poo
http://localhost/wconnect/wc.dll?_maintain~ShowStatus
(or wc.dll in your own application path).
This page provides status information about the current status of your running Web Connection Application. This page reads the live status of the ISAPI dll that's currently running on the server and echos back the common values. The page looks like this:

The status on this page is very useful for debugging any problems you might be having with your server as well as telling you most of the important settings of the server. The values are as follows:
DLL Version
This is the version of the Web Connection ISAPI dll (wc.dll). This version id is compiled into the DLL and echoed back. Note that this is the official way to check the WWWC version, even though there's a version resource compiled into the DLL as well. The version resource may sometimes be out of date while this value is always up to date.
Current Ini File
This is the location of the configuration file the wc.dll is currently using to read values from. This INI file should be in the same directory as your wc.dll. If you're seeing a different directory here than you are expecting it's possible that IIS is mismapped or a scriptmap is pointing to the wrong copy of wc.dll!
File Template
This is the template prefix used for file based messaging. This value is retrieved from wc.ini at startup.
Temp File Path
The location of the temp file path where file based messaging is depositing message files. This is also the directory where the error log sits.
Admin Account
This is the account or accounts that is required to access admin functionality in Web Connection. If this value is blank you should immediately assign this key a value in the wc.ini file.
Current Login
Shows you your current login name. This value should read your current user account or SYSTEM. If it reads IUSR_ or IWAM_ you have a security problem as this page would be openly accessible.
Messaging Mechanism
Determines whether COM or File based Messaging is used at the moment.
Post Mechanism
Determines how messages are posted. Supports UrlEncoded which is the default and INI based which is based on the outdated Windows CGI specification.
COM Server Loading
Determines how COM Servers are accessed. Sequentially (normal in wc.ini) uses the default order of servers, so the first available server is used. Round Robin attempts to go to the next server in the round. Sequential makes it easier to see how loaded the server are, but Round Robin spreads the load more evenly among the active servers.
ISAPI ECB Object
Determines whether a reference to the ISAPI COM object is passed to a COM Server. The ECB object allows access to writing out content immediately to the output stream.
Hold Requests
Determines whether the server is currently Running or On Hold. The Switch link allows to swap operation.
Lock, Recursion and Spin Count
These settings are internal debug settings that determine the state of Critical Sections in the ISAPI DLL. The lock count should be -1 (no locks) or a low number which shows the number of threads waiting on locks. Recursion and Spin are related and these values should be 0.
The COM Server Grid
The grid
<?xml version="1.0"?>
<webconnectionconfig>
<version>Web Connection 4.35 (32 servers)</version>
<inifile>d:\westwind\wconnect\wc.INI</inifile>
<template>wc_</template>
<scripttimeout>120</scripttimeout>
<temppath>d:\temp\wc\</temppath>
<adminaccount>rstrahl</adminaccount>
<messagingmechanism>COM</messagingmechanism>
<comserverloading>Round Robin</comserverloading>
<comkeepalive>Force</comkeepalive>
<holdrequests>RUNNING</holdrequests>
<lockcount>-1</lockcount>
<recursioncount>0</recursioncount>
<spincount>0</spincount>
<comservers>
<server>
<progid>wcDemo.wcDemoServer</progid>
<hits>774</hits>
<currentseconds>0</currentseconds>
<cumulativeseconds>31</cumulativeseconds>
<started>17:40 - 4/5/2003</started>
<processid>1708</processid>
<serverid>0</serverid>
<terminationurl>/wconnect/wc.dll?_maintain~KILL~0</terminationurl>
</server>
<server>
<progid>wcDemo.wcDemoServer</progid>
<hits>774</hits>
<currentseconds>0</currentseconds>
<cumulativeseconds>38</cumulativeseconds>
<started>17:40 - 4/5/2003</started>
<processid>2264</processid>
<serverid>1</serverid>
<terminationurl>/wconnect/wc.dll?_maintain~KILL~1</terminationurl>
</server>
</comservers>
</webco
The maintenance page contains a Show DLL Errors link you can use to view the log.
There are a number of errors that are generated in this log that are not critical - they're reported for your information and debugging purposes. Harmless errors include:
All servers are busy
If your server pool is too busy to take further requests in the allocated timeout period you'll see this error message. This is not really an error, but merely a notification that your server is maxed out.
Forced Release of Server
If you're running Automation servers are unloaded by releasing the COM references which release the object when the reference count goes to 0. In some instances related to the multithreaded nature that Web Connection objects are called from the reference counts alone do not allow the objects to unload. In these cases the Web Connection DLL forces the objects to unload by terminating the process explicitly. This is normal for servers that have been running for long periods of time, especially if you use the KeepAlive flag on your server. This information is logged merely for informational purposes.
Web Connection Request timed out
This means that a request took longer than the allotted timeout period as specified in wc.ini. This either means you had a very slow request or possibly your server hung on an error or some unexpected UI operation. If the Web server is busy the offending server was probably unloaded automatically and reloaded. This error is also common when working with file based operation and testing development installations. Anytime you hit a WC link and don't have the server running one of these messages will eventually be generated when the request times out.
GetIDsOfNames or QueryInterface Failed due to thread Time Out
Web Connection Server has been unloaded (RPC Server Unavailable)
These errors relate to crashed or killed Web Connection servers that unloaded while they were idle. When Web Connection tries to access these server these errors occur. These errors are actually trapped and the server are automatically reloaded at that time so that the client never sees an error in most cases.
The errors above are all benign and are nothing to worry about even if you see a lot of them. There are also permission errors related to maintenance tasks which also are not crucial. Errors to watch out for are:
Exception Errors
Unhandled exception errors are caused by system errors (like heap corruption, corrupted memory) and believe it or not code errors <s>. If you have isolated exception errors that occur very rarely it's nothing to be worried about - IIS has been known to get unstable and memory/COM subsystem errors are something that will occur from time to time. In my experience these errors are very few indeed and most don't manifest themselves as serious to require even a Web server shutdown/restart.
If you run into consistent exception errors make a note of the error message (the nature of exceptions makes this necessarily vague but some will report a little info) and try to get as much context as you can to report the issue. What is the server doing, what types of requests are you running when the problems occurred etc.
Note:
upgrades from version 3.x to 4.x don't require any special upgrade steps
Keeping your applications current when Web Connection changes is an important activity. This section covers two very different areas:
Updating consists of the process of moving your Web Connection 3.x applications from one version to the next.
Migration is a one-time process to move version 2.x applications to Web Connection 3.x. Once migrated, all future version releases are handled by updating.
These two subjects are covered in detail as follows:
The best way to handle this is to copy the following files to the server from your local Web Connection installation to your Exe's application directory:
This only copies the updated files to your 'installation' path. To update the files in your web application you need to perform an additional step. You can do this manually or use an automated link.
http://localhost/yourVirtual/WebResourceUpdate.wc?wwMaint~WebResourceUpdate
This operation updates:
Note that westwind.css is not explicitly overridden unless you click on the link that is presented. This is done because frequently developers change westwind.css for their applications themselves and we don't want to override your changes.
Note that this routine updates your wc.dll and webconnectionmodule.dll files one of which is likely going to be loaded in memory at the time of the update. This means that even if there's no error updating the active DLLs is not actually updated and running until you restart the Web service.
The figure above demonstrates that you can set breakpoints and step through live Web requests in the VFP debugger.
Come deployment time you can set DEBUGMODE to .F. and all of Web Connection's Error handlers kick in to provide bullet proof trapping of errors so that your server doesn't crash or hang. With error handling enabled an error message is displayed (calling the wwProcess::ErrorMsg method to display the error) and logging the error into the RequestLog file. This message can be customized by overriding the ErrorMsg method for display purposes and the Error method for custom error handling.
The DEBUGMODE flag is contained in wconnect.h. It's a constant in a header file and in order to change this flag you have to recompile your server application. For more info See the Error Handling topic.
Use this feature to check output and make sure that you are returning exactly what you're expecting to return. One important thing to look for is the HTTP header of the resulting HTML document. The Request data file input can be very useful in seeing whether all the form variables from a form are retrieved. This lets you see exactly what the server is sending you on each request and lets you access some of the keys that are not exposed directly by the wwRequest class methods. Other things you can use the request data for is verifying that input contains expected cookies and authentication tokens which would otherwise be difficult to debug and troubleshoot.
Make sure you use this feature whenever you see inconsistent inputs in your application. The request input data comes directly from the Web server and passed straight through the ISAPI extension - if it's not there the Web server didn't send it!
Using the wwProcess::lShowRequestData flag
You can use the wwProcess::lShowRequestData flag to force the full request data to be appended to the end of a HTTP Response (actually it work correctly only with HTML content because any other content type might get corrupted by the data at the end). You can do this either at the request level by setting it in the method you're calling or at the process level.
Method level:
Function DoSomeThing
THIS.lShowRequestData = .T.
Response.HTMLHeader("Test Page")
...
Response.HTMLFooter()
ENDFUNC
Process level:
************************************************************************
*PROCEDURE wwDemo
******************
LPARAMETER loServer
LOCAL loProcess
#INCLUDE WCONNECT.H
loProcess=CREATE("wwDemo",loServer)
loProcess.lShowRequestData = .T. && loServer.lShowRequestData
loProcess.Process()
*** Class definition follows here
Note that you can optionally read the loServer.lShowRequestData flag which is loaded from the application's INI file using the ShowRequestData flag.
The DebugMode flag can be set in the following places:
Essentially when debug mode is .T. errors stop at the source of the error with Web Connection removing it's core error handlers from the error chain, so that you can fail at the point of error and fix the problem any way that makes sense. If lDebugMode is set to .F. Web Connection's error handlers kick in and errors are handled and routed to predefined error handlers of the framework.
Default error handling behavior is provided and you can override this behavior. Error handlers exist in:
Note that the Server.lDebugMode flag is new for Web Connection 5.0 and superceeds the #DEFINE DEBUGMODE flag. The DEBUGMODE flag from WCONNECT.H is no longer used by the Web Connection framework.
The documentation on wwProcess::lUseErrorMethodErrorHandling provides more information on how to configure this more complicated mechanism that requires use of #DEBUGMODE compilation flag as in Version 4.x.
Templates simply evaluate expressions and code and if an error occurs they embed an error message into the document instead of the result that should have been there:
< % Error: ErrorExpression % >
Expressions are run through the wwEval object and errors are trapped through this mechanism. However, no indication is given as to what caused the error at this point. This method works well for catching errors without doing damage to the system even when evaluating unknown code, but it's not terribly easy to see what the problem is especially if the failure occurs in a code block.
Use this feature to check output and make sure that you are returning exactly what you're expecting to return. One important thing to look for is the HTTP header of the resulting HTML document. The INI file input can be very useful in seeing whether all the form variables from a form are retrieved. This lets you see exactly what the server is sending you on each request and lets you access some of the keys that are not exposed directly by the wwCGI class methods.
Both mechanisms log a unique RequestId which identifies each request.
lcID = Request.ServerVariables("REQUESTID")You can use this ID to track requests through the entire Web Connection processing cycle. The DLL uses this id for all logging purposes and you can write out the request ID as part of any custom logging your application does.
Web Connection also uses this ID to safeguard any possible corruption in requests and provide request tracking for logging purposes from your own application and the ISAPI extension. To enable this checking (which creates a tiny bit of overhead) set the following key in wc.ini:
ValidateRequestId=1
The ISAPI Dll sends the ID to your server, which then returns a RequestId header as part of the response. The ISAPI DLL then checks for the header, extracts the ID and validates it against the original ID generated for the request before the output is sent back to the client. If the IDs don't match - and this should never happen - the response is not sent to the client and an error message is displayed instead. This guarantees beyond any possible doubt that there might be any possible request mixups.
To ensure our customers of the security of the Web Connection framework, Web Connection uses an explicit check for the Request ID after the result has been returned from the FoxPro server to ensure that the request integrety is fully intact. If the RequestId HTTP header is returned from the Fox server this header is checked and compared against the original request id to ensure the ids match. If for whatever reason they don't an error page is displayed instead of displaying potentially incorrect data.
Starting with Web Connection 5.10 the header is automatically added with any request that uses the wwPageResponse class or the wwHTTPHeader class for explicit or implicit headers with earlier Request class versions if the ValidateRequest key is enabled.
On failure an error message will display. On IIS 6 or later if the problem should occur Web Connection will shut down the worker process and restart it automatically as the cause of this sort of mismatch is almost certainly due to COM object corruption which cannot be resolved without a restart.
The Log is turned on via a switch in <YourServer>.ini file with:
[Main] Logtofile=On
which is mapped to the wwServer.lLogToFile. When .t. at the end of the request wwServer.LogRequest is called to log the request into the file specified in wwServer.cLogFile which defaults to wwRequestLog.
Logging can occur in two formats - simple and extended.
Simple Logging log the current script and querysting, timestamp, remote IP, duration and memory used. The extended logging also adds the browser user agent and POST data if any. Note that using extended logging can become very verbose quickly so make sure you clear out these files frequently or copy them off.
You can view the log either as a DBF file directly or you can view it from the Server Status form. Click Status and Browse Log.
The ISAPI request creates a unique RequestId at the beginning of the request which consists of an ISAPI threadID and a GUID. This value is passed through the entire request and to your FoxPro server application where it becomes available as Request.ServerVariables("REQUESTID"). The FoxPro Server also picks up this value and logs it in the request log if logging is enabled.
The ISAPI extension can also log every request into it by setting the wc.ini LogDetail key to 1. If set to 1 every request is logged when it starts and when it exits the DLL. Here's a sample of what this looks like:
2006.02.6 02:50:02:359 - 2428_D8152FCDDCE5 - Request Started - /wconnect/wc.dll?_maintain~ReadSetupIni - 122
2006.02.6 02:50:02:359 - 2428_D8152FCDDCE5 - Request Completed (0) - /wconnect/wc.dll?_maintain~ReadSetupIni - 3
2006.02.6 03:12:47:421 - 2428_5B5EC48F1980 - Request Started - /wconnect/wc.dll?wwDemo~ShowImage - 122
2006.02.6 03:12:47:531 - 2428_5B5EC48F1980 - Request Completed (109) - /wconnect/wc.dll?wwDemo~ShowImage - 3
2006.02.6 03:12:58:218 - 4188_ABAD0B86AE31 - Request Started - /wconnect/weblog/default.blog? - 122
2006.02.6 03:12:59:750 - 4188_ABAD0B86AE31 - Request Completed (1531) - /wconnect/weblog/default.blog? - 3
2006.02.6 03:13:06:671 - 4188_96F7C8213A96 - Request Started - /wconnect/weblog/default.blog? - 122
2006.02.6 03:13:07:437 - 4188_96F7C8213A96 - Request Completed (765) - /wconnect/weblog/default.blog? - 3
2006.02.6 03:13:08:734 - 4188_14A1C723EAC7 - Request Started - /wconnect/weblog/admin/default.blog? - 122
2006.02.6 03:13:09:171 - 4188_14A1C723EAC7 - Request Completed (438) - /wconnect/weblog/admin/default.blog? - 3
Each entry logs a timestamp, the request Id and a message - in this case start and stop messages. Stop messages include a tick count in parenthesis which is the time it took to process the request.
End messages can sometimes not get logged if a hard exception occurs. In that case you should see a different kind of message for a specific id logged instead.
Web Connection's internal mechanisms to do this include:
Standard scalability mechanisms available include:

Remember, large scale application require a fair amount of hardware and network know how - make sure you have staff or support available that understands scalability, infrastructure, security and deployment issues in large scale environments.
For more information on scalability scenarios see:
Building Large Scale Web applications with Visual FoxPro.
Building a Web Farm with Windows 2000's Network Load Balancing service
My recommendation for scalability for large application is with the latter approach - it's more reliable and provides full redundancy as well as more efficiently balancing resources across machines than Web Connection built-in mechanisms. It's also an accepted standard for scaling Web applications in a tiered environment.
DCOM is a good choice for a quick fix, but as you'll see below configuration can be daunting especially if you don't have a firm grasp on how COM and the distributed architecture works. More info is available in the Large Scale Web apps article described above.
The following sections delve into the details of configuring Web Connection's internal mechanisms for moving out over the network.
When building a server that will run on multiple machines simultaneously it's important to set up your pathing correctly so that a single EXE file can be run on every one of these machines and still point at common data accessed on a network path. The following tips are suggestions only - you may configure your servers differently to be able to share data, but the following steps have worked well for me here:
These files are optional and can be turned off. For SQL applications these files can be ported into a SQL database with some modifications to the wwSession and wwServer classes.
The above suggestions apply to any network servers built regardless of whether you use Automation or File Based messaging.
No special setup is required on the Web server or with wc.dll/exe/ini. The server operates as before placing the files onto its local drive. The VFP Web Connection server on the other hand is now looking across the network, polling for incoming requests on the Web server's drive. So for the remote server it's TEMPFILEPATH is going to be z:\temp\ for example.
All filenames returned by the wwRequest class methods are automatically mapped to this from the Web server's path (ie. c:\temp\) to the network path (ie. z:\temp\). The actual filenames will be Web server pathed - the translation is necessary to properly translate the path into the network path, so that no code changes are required internally when moving a Request process off the local machine onto the network.
As with file based messaging make sure all your application paths are pointing across the network at the appropriate remote files if data is shared. Establish a Network startup path. This means any common data files (such as the Web Connection Log or Session tables) as well as any other file based resources such as INI files that you might want to access.
In order to run Automation remotely you run Distributed COM (DCOM) across the network. The steps to remote a server rather complex to set up.
o=CREATEOBJECT("test.testserver")
o.ProcessHit("query_string=wwmaint~Fasthit")Make sure you have your pathing properly corrected to adjust for access across the network using UNC pathing. For example, if your data sits on the local C: drive build your data access so it points at: \\YourServer\CROOT\DATA\MyFile rather than accessing the drive letter (unless you can guarantee drive maps - drive maps are significantly faster than UNC names).
o=CREATEOBJECTEX("test.testserver","REMOTESERVER")
? oProcess.GetProcessID(0)
? o.ProcessHit("query_string=wwmaint~Fasthit")This should work assuming your current user account has the DCOM rights described above to access the COM object on the remote server. If there is a problem note the problem: Access denied errors most likely are caused by invalid DCOMCNFG settings. CoCreateInstance errors or other instantiation problems are caused by the server not being registered correctly or a mismatch between the client and server class ids. Make sure the server versions are identical and re-register the server in that case.
[Automation Servers] Server1=wwDemoOle.wcDemoServer Server2=wwDemoOle.wcDemoServer,RemoteServer Server3=wcRemote.wcRemoteServer,OtherRemoteServer
The first step for high volume applications should be to tune the application so it is optimized to perform as fast and efficiently as possible. For a number of hints on how to tune your Web application, the Web server, the machine, database operations and code check out:
http://www.west-wind.com/presentations/largeweb/
This article describes a number of things to optimize performance.
The next step, which is also described in the above article is tune your application for the hardware it is running under. This process involves stress testing the Web application with a Web Stress tool such as Microsoft's Web Application Stress Tool (WAST). You can find out more about stress testing and how to use this tool at the following URL:
http://www.west-wind.com/presentations/webstress/webstress.htm
This article describes the process of stress testing as well as general concepts of what it takes to balance machine resources against the running application. The concepts in the article are fairly general, but apply to a Web Connection application as well.
Understand that performance is a relative thing and depends entirely on your application. For example, in simple test scenerios we've run Web Connection with over 350 requests/second, but this is an unrealistic expectation for an application that actually performs something useful. The above is sort of a raw throughput number, which will drastically decrease once you do actual work in your code. So a typical transaction based business application with short (.10 second or less) requests will generally run somewhere around 50-100 requests a second. Your data, business and output generation logic will determine exactly how scalable your application is. Remember that long running requests are the killer of scalability!
For Web Connection applications specifically, the key factor is balancing CPU usage against the number of instance that are run. As a general rule for high performance applications use these settings as a starting point:
Typical Web applications talking to a SQL backend will want to maintain a permanent connection to the SQL backend. This is easily accomplished by using a wwSQL object instance and attaching it to the wwServer object. The logging and Session features do this using a special oSQL property which is available, but you can also use AddProperty to create a custom object:
FUNCTION SetServerEnvironment ... THIS.AddProperty("oSQLConn",CREATEOBJECT("wwSQL")) THIS.oSQLConn.Connect("DSN=Pubs;uid=sa") ... ENDFUNC
Once this object is initialized it can be easily accessed in the application's wwProcess methods:
FUNCTION SQLTest Server.oSQLConn.cSQLCursor = "TResult" Server.oSQLConn.Execute("Select * from Authors") IF Server.loSQLConn.Error THIS.ErrorMsg("SQL Error occurred",Server.oSQLConn.cErrorMsg) RETURN ENDIF *** Display an HTML table from SQL result Response.HTMLHeader("SQL Demo") Response.ShowCursor() Response.HTMLFooter()
If you are sending logging and session data to your database as well you can use the Server.oSQL (wwProcess::oServer::oSQL) property to keep everything on a single connection. If you have your own SQL objects and would like have the Web Connection logging and session features share the connection to your existing database you can assign the oSQL.nSQLHandle and oSQL.cConnectString properties once the connection has been made. This will allow Web Connection to reuse your existing connection without requiring an additional connection.
wwSQL is a very simple object - it doesn't help with proper design of a SQL application, but I would recommend using it or a wrapper like it to handle SQL connection errors which is messy to deal with in mainline code. wwSQL is fairly lightweight and supports all that SQLPassthrough provides.
After you've worked through this guide we recommend you check out the Step By Step with the wwBusiness Object guide, which uses the wwBusiness object to handle data access. Besides using the business object and showing how to utilize a business object in a Web based application, it also shows a few more advanced techniques for generating HTML interfaces in your applications.
Web Control Framework Note:
Web Connection 5.0 features a new Web Control Framework which provides a different mechanism for creating pages and processing requests. If this control based approach is more appealing to you, you should take the Web Control Framework Walk Through. We still recommend looking at this Step by Step Guide first unless you are already familiar with Web Connection as this walkthough demonstrates many core featues, like using the Request and Response objects, Sessions and providing a general overview of the framework that also applies to Web Control Framework applications.

Click on the Create New Project button to create a new Visual FoxPro project that includes the base Web Connection framework classes and the startup code.
Note to shareware users:
The Shareware version cannot build a Visual FoxPro project or EXE file due to the fact that the shareware version is precompiled. The full version comes with source code and allows to create a 'real' project. However, you can still run the application by simply running the PRG files as mentioned below.
In the Wizard that pops up start by naming the project and the main process class. The project name should be the filename of the project you want to create. Use a single string value without spaces for this setting. In this case it's WebDemo.
The filled out page now looks like this:
A Process is the actual request handler class, where you will write your logic to handle Web requests. A single project can contain several Process classes. In this case we're going to create a new project and add our first Process class called WebDemo. You can later add additional Process classes using the New Process Wizard.
To make it real obvious which pieces I'm talking about in this demo I'll name the project WebDemo and the process WebProcess.
I also need to specify the Web server I'm planning on using, in this case IIS 6. Note that it's important that you pick the correct Web Server, especially in the case of IIS 6. IIS 6 is heavily locked down and this Wizard sets up a number of settings to make sure that your new project can run.
Step 2 of the Wizard now asks you to set up the Web directory for this application by creating a virtual directory, copying the Web Connection ISAPI connector to it and configuring the application settings for the new application.
The filled out dialog looks like this:
Note that the Web path can be anywhere but should point somewhere into your Web directory structure. Above the default \inetpub\wwwroot\ basepath is chosen with the virtual created off that. The Temp file path is open to your choice, but make sure that the directory allows FULL access user rights to the IUSR_ account or Everyone so that the ISAPI extension can read and write files to this directory.
Step 3 lets you configure a script map for your application. A script map is a file extension that maps to the Web Connection ISAPI DLL that makes it easier to reference requests. Once mapped any request to a 'file' or URL with this extensions maps to the Web Connection DLL.
Start with the extension you