If you’re working with Windows, your definitely familiar with the sight of the “[Application] has stopped working” ™ dialog
Whether that is good or bad in general? I don’t care. Not today at least. I am much more interested in a particular use case where this is most certainly not what you want. That case is if you run another application as a sub-process using the System.Diagnostics.Process class. Maybe you’re running other applications that simply crash occasionally and you want to automatically restart them, maybe you just don’t want the users to know. In any case, if the sub-process pops up with this dialog it doesn’t terminate the actual process until one of the buttons is clicked which is absolutely not what I wanted in my use case.
So here’s how to solve that: There is the Win32 API function SetErrorMode (http://msdn.microsoft.com/en-us/library/windows/desktop/ms680621%28v=vs.85%29.aspx) that allows you to suppress different types of error dialogs, one of them being the “[Application] has stopped working” dialog. The error mode you set using this method is automatically inherited by child processes which is exactly what I needed. Since directly working with Win32 calls is always kind of icky, I created a nice little wrapper for this functionality. It consists of the class ErrorModeContext and the enum ErrorModes
public class ErrorModeContext : IDisposable { private readonly int _oldMode; public ErrorModeContext(ErrorModes mode) { _oldMode = SetErrorMode((int)mode); } ~ErrorModeContext() { Dispose(false); } private void Dispose(bool disposing) { SetErrorMode(_oldMode); } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } [DllImport("kernel32.dll")] private static extern int SetErrorMode(int newMode); }
[Flags] public enum ErrorModes { Default = 0x0, FailCriticalErrors = 0x1, NoGpFaultErrorBox = 0x2, // <- this is the one we need NoAlignmentFaultExcept = 0x4, NoOpenFileErrorBox = 0x8000, }
I have implemented the ErrorModeContext as an IDisposable so that I can use it in a using block with the auto-cleanup feature. I just place the code that runs my child process inside a using block and the problem disappears.
using (new ErrorModeContext(ErrorModes.FailCriticalErrors | ErrorModes.NoGpFaultErrorBox)) { // start child process // and wait for it to finish }
#
This is great! Solves many problems and could replace thousands of discussions and forum posts or registry messing and strange solutions I have read about all day now.
Thanks!
#
I could kiss you.