Feb 1st, 2009, 11:24 PM
[VB6] Set Unattended and/or Retained In Memory at runtime
This won't mean much to most programmers, but to those it does it may be useful.
You can configure the Unattended Execution option and the Retained In Memory option in the latest version of Msvbvm60.dll
The significant thing not apparent from this MS KB article is that it also works for Standard EXE projects. This is something you can't do using the Project|Properties... dialog in the IDE.
You must turn on the Unattended Execution option and the Retained In Memory option before compilation to host a Microsoft Visual Basic Enterprise Edition for Windows 6.0 component (Microsoft ActiveX DLL) in a multi-threaded environment, such as Microsoft Transaction Server (Mtx.exe), Internet Information Services (Inetinfo.exe), COM+ (Dllhost.exe), and Microsoft SQL Server 7.0 or SQL Server 2000 (Sqlservr.exe). However, you may not know whether a component is going to be used in such an environment or you may forget to turn on the Unattended Execution option and the Retained In Memory option. To address this problem, the latest version of the Visual Basic runtime (Msvbvm60.dll) introduces a new feature that permits you to turn on the Unattended Execution option and the Retained In Memory option at run time. This article discusses how to configure these options and what to be aware of when you turn on these options at run time.
Now, why would you want to do this for an EXE?
While Retained In Memory is not so important in such cases, setting Unattended can be very useful in specific situations. The situation at hand for me is a program that is used as a Windows Service (though I believe that NTSVC.ocx takes care of this if I am not mistaken) or a child process of a Windows Service.
One of the more important effects of setting Unattended is that it suppresses GUI dialogs. Or more specifically it redirects many of them to the system Application event log:
This includes MsgBox calls as well as unhandled exception dialogs.
Indicates that the project is intended to run without user interaction. Unattended projects have no interface elements. Any run-time functions such as messages that normally result in user interaction are written to an event log.
The point is, you don't want such a Service (or Service child) hanging awaiting someone to Ok or Cancel some dialog!
It also gives you another way to log messages when desired (MsgBox) instead of the logging you can do via the App object. That's mostly incidental, however using MsgBox may prove useful during testing where App.LogEvent might be a pain. I haven't tried it but I assume an InputBox call would also be logged and return a Canceled result.
I have attached a short (and somewhat simple-minded) demo. It loads an invisble Form and then calls MsgBox to report the value of App.UnattendedApp to you. You should find that it will always report as False.
The Form simply starts a 1-second Timer control going, and in the event handler a counter is incremented and then displayed via MsgBox. Once the Timer hits 4, a division by zero is attempted to illustrate and unhandled exception.
This terminates the application.
When run via the IDE everything appears as you'd normally expect, MsgBox calls creating dialogs and the unhandled exception causing a final dialog. But when compiled, with the .cfg file alongside it, the VB6 runtime runs the program in unattended mode. Things run silently, and after the Timer count hits 4 you can check the Application log for the results.
This of course requires the VB6 runtime version 18.104.22.168 or later. VB6 SP6 (or later: Vista, XP SP3, etc.) are just fine.
That's about it. Not too exciting to the average Joe, but handy if you need it.
And it serves the documented purpose as well.
Click Here to Expand Forum to Full Width