Posts Tagged ‘COM Object Debugging’

A .NET Application that Never Dies

Saturday, September 12th, 2009

29392-Live_forever_-sfullJeremy's Graceful Shutdown Braindump should really include another use case. How do you create a .NET application that never shuts down? Ever!

This  is a common scenario for closed systems that only allow the user to interact with a predefined set of applications.  In other words, the user is never able to utilize any of the operating system functionality. In particular, they can not install new applications or update any software components.

This situation is related to the issues discussed in Medical Device Software on Shared Computers. Creating a closed Windows-based system is not an easy task. For our XP Embedded system here are some of the considerations:

  1. Prevent booting from a peripheral device (CD-ROM, USB stick, etc.)
  2. Prevent access to the BIOS so that #1 is enforced.
  3. Prevent plug-n-play devices from auto-starting installers.
  4. You can not run Explorer as the start-up shell -- no desktop or start menu.
  5. Prevent Ctrl-Alt-Del from activating task manager options.
  6. Disable the Alt-Tab selection window so the user can not switch application focus.
  7. Ensure that the primary user interface application is always running.
  8. All UI components must exit without user interaction when the system is powered down.

One of the challenges for .NET applications is how to handle unexpected exceptions. What you need first is a way to catch all exceptions.  OK, so now you know your program is in serious distress. You may be able to recover some work (a la a "graceful shutdown"), but after that it's not a good idea keep the application running.

That means you have to restart the program. For a WinForm application one option is:

Application.Restart() essentially calls Application.Exit() which tries to gracefully shutdown all UI threads.   The problem with that is the application may appear to be hung if you have background worker threads that are monitoring hardware devices that are not currently responding.

Another issue is when the .NET application is doing interop with COM components.  I've seen situations where all of the managed threads appear to exit properly via Application.Exit() but an un-managed exception (and error window) still occur.  This behavior is unacceptable.

The way to ensure that the application restarts properly (simplified):

The Environment.Exit() call is harsh, but it is the only way I know of that guarantees that the application really exits.  If you want a Windows Application event log and a dump of your application you can use Environment.FailFast() instead.

UPDATE (9/19/09): I ran across a post about COM object memory allocation in mixed managed/unmanaged environments: Getting IUnknown from __ComObject. As this article exemplifies, debugging COM objects under these circumstances is a real pain in the butt.  We used strongly-typed managed wrappers for our COM objects. Besides a .NET  memory profiler we just monitored overall allocations externally with Process Explorer. It may be undocumented and fragile, but at least it's good to know that there is way to dig deeper if you need to.