Deshabilitar el cuadro de diálogo Informe de errores de Windows (AppCrash) mediante programación

Estoy ejecutando un proceso en la aplicación .NET.

                Process process = new Process(); 

....

                process.StartInfo.UseShellExecute = false;
                process.StartInfo.ErrorDialog = false;

                process.StartInfo.CreateNoWindow = true;
                process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
....
                process.Start();

El problema es que el ejecutable a veces falla, lo cual está bien, pero aparece el dialg AppCrash e impide que la aplicación continúe con la ejecución hasta que haga clic en cerrar.

Sé que puedo establecer HKLM\Software\Microsoft\Windows\Windows Error Reporting\ valor Deshabilitado a verdadero - msdn.microsoft.com/en-us/library/bb513638%28v=vs.85%29.aspx

Pero, ¿hay alguna manera de que pueda hacer esto en código?

EDIT:

kmp ha publicado una excelente respuesta, pero todavía estoy buscando cómo lograr lo mismo con la aplicación nativa.

preguntado el 24 de agosto de 12 a las 05:08

2 Respuestas

Si puede editar el código del proceso de bloqueo, lo que puede hacer es agregar un código como el que muestro a continuación (este artículo habla de eso: Deshabilitar el cuadro de diálogo de bloqueo del programa) - ver Función SetErrorMode para obtener información de MSDN sobre esta función de la API de Windows.

Si no puede modificar el código de la aplicación que falla, es más complejo y tendría que inyectarle código en tiempo de ejecución (la complejidad depende de en qué esté escrito el proceso que está iniciando; si es un proceso .NET, es más fácil que una aplicación nativa, por ejemplo, por lo que deberá proporcionar más información sobre ese proceso).

[Flags]
internal enum ErrorModes : uint 
{
    SYSTEM_DEFAULT = 0x0,
    SEM_FAILCRITICALERRORS = 0x0001,
    SEM_NOALIGNMENTFAULTEXCEPT = 0x0004,
    SEM_NOGPFAULTERRORBOX = 0x0002,
    SEM_NOOPENFILEERRORBOX = 0x8000
}

internal static class NativeMethods
{
    [DllImport("kernel32.dll")]
    internal static extern ErrorModes SetErrorMode(ErrorModes mode);
}

// Ideally the first line of the main function...

NativeMethods.SetErrorMode(NativeMethods.SetErrorMode(0) | 
                           ErrorModes.SEM_NOGPFAULTERRORBOX | 
                           ErrorModes.SEM_FAILCRITICALERRORS | 
                           ErrorModes.SEM_NOOPENFILEERRORBOX);

Respondido 24 ago 12, 11:08

Gracias, pero no puedo modificar el proceso de bloqueo. El ejecutable es un código nativo. La aplicación es gswin64c.exe se puede encontrar en este archivo: downloads.ghostscript.com/public/gs906w64.exe - user1615362

Entonces, ¿alguna idea de cómo puedo inyectar esto en una aplicación nativa? - user1615362

Funciona genial. Tal vez la inyección no sea necesaria cuando se trata de una aplicación administrada. Podría crear una aplicación contenedora, que establecería estos indicadores y luego cargaría el ensamblaje de la aplicación real (no un proceso nuevo) y ejecutaría Program.Main() usando la reflexión, pero es solo una idea, no la he probado. - Ondra

trabajó para mi. Usé este NativeMethods.SetErrorMode (ErrorModes.SEM_NOGPFAULTERRORBOX | ErrorModes.SEM_NOOPENFILEERRORBOX); - John C

¿Hay alguna forma de reiniciar mi aplicación después de un bloqueo? - mrid

Según este documento debería ser posible heredar el SetErrorMode valor para el proceso hijo. Entonces, cualquier tipo de lanzador (o su aplicación principal) que SetErrorMode a los valores requeridos y luego ejecutar su aplicación nativa debería funcionar. En realidad, esta herencia existe por defecto. Para apagarlo ver banderas aquí.

Respondido el 04 de Septiembre de 17 a las 12:09

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.