Rick Strahl's FoxPro and Web Connection Web Log
White Papers | Products | Message Board | News |

Understanding wwServer::lUnattendedComMode

Tuesday, December 29, 2009, 12:00:00 AM

In Web Connection 5.x and later a new server property called lUnattendedComMode was introduced. This flag controls how user interface interaction occurs by setting SYS(2335,0). This command is described in the FoxPro help file as follows:

Enables or disables modal states for distributable Visual FoxPro .exe automation servers.

SYS(2335 [, 0 | 1])


This is a rather desirable feature for a server application as it helps avoid accidentally popping up a MessageBox or Wait Window or other UI construct that has the potential to hang your server. It also forces VFP to surpress a few of the dialogs that can’t be handled via error handling – specifically file/table open dialog boxes which are untrappable errors if you don’t use SYS(2335,0).


The lUnattendedMode property is nothing particularily special – you could always in the past do this yourself manually by specifying SYS(2335,0) in code somewhere in your server startup code.


However, there are a few problems with this approach and a few things you need to be aware of. First off Web Connection internally has a few places where WAIT WINDOW TIMEOUT or WAIT WINDOW NOWAIT is called, and due to an unfortunate decision to include WAIT WINDOW in the SYS(2335,0) controlled ‘modal states’ that code can fail. Most of these are present in the server’s user interface – the Web Connection status form. But there are also a few places in the demos and sample applications that also use WAIT WINDOW which also breaks.


Your own code that uses WAIT WINDOW will have a similar fate: The commands are simply treated as errors and if you have debug mode off will cause the error to force an error page.


Changes in Web Connection 5.51


In Web Connection 5.51 a few changes have been made to make the unattended mode a little less restrictive. In prior versions SYS(2335,0) was applied during the server’s startup code after the user called OnInit() call. This was meant to capture startup errors and throw exceptions there if something goes wrong.


This does exactly what it should, but the result is not really desirable:

Unable to load servers.

The application COM servers could not be loaded:

Creating an instance of the COM component with CLSID {17F10C95-B12E-4EF2-A062-9ABC85168AC2} from the IClassFactory failed due to the following error: 80004005.

Message generated by Web Connection IIS Connector Module


The problem is that both OnInit() and OnLoad() are effectively fired during the COM server’s instantiation sequence which means if an error occurs during this phase the server instance is never created. Also unfortunately the COM error info is not sent back to the COM client in the ISAPI DLL or Web Connection .NET Module. The result is the above which is a generic COM error message that COM object creation fails which is not terribly useful.


Unfortunately there’s not much that can be done to improve this process precisely because the object is not actually instantiated yet. For this reason loading SYS(2335,0) in OnInit or OnLoad() in general is not a great idea.


So in Web Connection 5.51 lUnattendedComMode now sets SYS(2335,0) around individual calls by wrapping the ProcessHit() method that starts off requests and then setting SYS(2335,1) when each request ends. This ensures that the unattended mode is only applied against process methods which are generally much less likely to have any UI related code in them.


This also allows the Web Connection server to keep its ability to still display some user interface functionality from the Web Connection status form. There are a handful of Wait Window Routines that are used to let you know that the log file was cleared, settings saved etc.


This also means that when the COM server launches errors now throw whatever errors occur in the FoxPro code – this can in certain circumstances mean hanging situations like file open dialogs and other failures. The advantage while debugging though is that you can see these errors popup if you’re running the COM Servers interactively. This can be tremendously helpful in debugging server startup as I found out today on a support call :-}.


If for whatever you reason you want to surpress modal interfaces and errors during startup as well you can still do that by setting SYS(2335,0) in startup code as always and that will cointinue to work just fine.


Web Connection 5.51 also cleans up a bunch of the WAIT WINDOWs in the samples. Most of these were silly and simply there to provide some feedback. Since that’s probably a bad example usage those are all being removed and I’m running the server in test.


In your own apps if you have situations where there is some UI operation required that you can’t remove you can always manually wrap the code with:


lnOld2335 = lnSys(2335)

SYS(2335,1)  && turn it off

WAIT WINDOW TIMEOUT 1 "This operation is REQUIRE bub!"

SYS(2335,lnOld2335)  && turn it back


SYS(2335) is a very efficient call in VFP so there’s no perf penalty for doing this sort of thing.


If you haven’t thought about unattended mode and you are running in COM mode, be sure to check it out – it’s a highly useful feature that can help trap a few errors that are otherwise untrappable in VFP – most commonly the File/Table open dialog boxes. To do this flip the UnattendedMode switch to On. in your YourApp.ini file and make sure that you have the error logging enabled so you can watch for potential failures in the log – those errors should tell you if you have any missed modal operations in your app. You might also want to use the CodeReferences and search for any WAIT WINDOW code in your project in case you’ve been careless with them as I’ve been…

As a final note: wwServer::lUnattendedComMode is totally optional. If you prefer to take your chances with modal interfaces that's absolutely supported since EXE COM servers are fully UI capable.

Posted in:

Feedback for this Weblog Entry

re: Understanding wwServer::lUnattendedComMode

Randy Pearson
You need to explain that this flag gets set by a Config setting, otherwise people will think they need to set the server's property in their subclass.


re: Understanding wwServer::lUnattendedComMode

Thank you very much for this article, Rick - you saved my day, again :)

re: Understanding wwServer::lUnattendedComMode

Dan Scott
Is there any chance this same issue could affect the VFP REPORT FORM command? As we are using the wwPDF class and when lunattendedmode is set to .T. we get User-interface operation not allowed at this time errors when trying to produce PDF. Works fine in file mode or if we set SYS(2335,1) before the:

REPORT FORM (lcReport) &lcExtraReportClauses NOCONSOLE TO FILE &lcTFile

command? Can't find any info on this and from my testing this is the case.

re: Understanding wwServer::lUnattendedComMode

REPORT FORM includes UI and so causes an error when running in unattended mode. The workaround is to turn of unattended mode before the report and then turn it back on afterwards (ie. SYS(2335,0) run report then SYS(2335,1)). This will work in an EXE. Note that DLL servers can't run REPORT FORM commands at all.

re: Understanding wwServer::lUnattendedComMode

Dan Scott
Thanks Rick. Yes, I thought that would be the case (even though the UI that report form shows when called with NOCONSOLE TO FILE is only a printing progress dialog). I wrapped the command in SYS(2335,0) and all worked fine. Of course if the FRX uses some cursors that aren't available then the server will still lock up with a file dialog, but I can't see any way around that! Thanks for your help.

re: Understanding wwServer::lUnattendedComMode

Mike McDonald
The line in the sample code above..
lnOld2335 = lnSys(2335)
..should be..
lnOld2335 = Val(Sys(2335))
..since Sys(2335) returns a character but expects a numeric input parameter.

Thanks for the details on this setting.


© Rick Strahl, West Wind Technologies, 2003 - 2018