2010-11-10 14 views
6

Tengo el siguiente problema: Utilizo la biblioteca C++ de mi aplicación WPF, la biblioteca arroja una aserción en algunos casos muy raros. Muestra un buen diálogo con el nombre de archivo C++, el número de línea y la expresión de afirmación. Entonces la pregunta es: ¿puedo desactivar las afirmaciones en la biblioteca C++ suponiendo que no tengo el código fuente? Lo que realmente necesito es "atrapar" esta afirmación y registrarla.¿Es posible desactivar C++ assert desde la aplicación .net

Gracias.

+0

¿Está provocando una afirmación o lanzar una excepción? – Ferruccio

+0

es una afirmación. La excepción no es un problema –

Respuesta

1

Según sus habilidades de ensamblador y si se han tomado medidas deliberadamente para bloquear este tipo de cosas, generalmente es posible modificar el código binario para evitar que se muestre este tipo de mensaje.

Sin embargo, una activación de afirmación es a menudo un precursor de una falla más espectacular u otra mala conducta, por lo que simplemente detener el cuadro de mensaje podría no llevarlo mucho más lejos. Por supuesto, algunas afirmaciones tienen fallas, por lo que esto podría ser todo lo que necesita.

Si tuviera que modificar esta DLL, la desensamblaría con IDA y elaboraría un parche. Ocultar la afirmación probablemente sería bastante fácil, registrarla mucho más difícil.

3

Una forma es crear un hilo que realiza EnumWindows cada cierto tiempo y detecta si una ventana aserción aparece, entonces se puede captar el mensaje y haga clic en el botón de ignorar. Esto todavía hará que la ventana se muestre por un corto tiempo (dependiendo de su intervalo entre EnumWindows pero supongo que los clientes no van a estar recibiendo la DLL de depuración por lo que no debería importar.


Otro opción está llamando _CrtSetReportMode(_CRT_ASSERT, 0) desactivar afirma que no se muestren por completo. Si desea PInvoke esto desde nota .NET que _CRT_ASSERT es igual a 2.

+1

El problema es que el dll fue desarrollado por otro equipo y afirma en el modo de lanzamiento :) es por eso que estoy buscando alguna forma de detenerlo. –

+0

@Alex, he agregado otra opción que creo que se ajustará mejor a sus necesidades. – Motti

+0

Motti, gracias por la idea. Lo intenté, no funciona. Supongo que la aserción es causada por assert Macros, pero tu solución funciona con _ASSERT. Parece que afirmar macro simplemente emerge un cuadro de diálogo con el mensaje de aserción :( –

0

recientemente tuve que solucionar algunos código antiguo que se basó en un archivo DLL que a veces apareció un mensaje afirmativo. Intenté todas las sugerencias anteriores, y la única que obtuve fue hacer clic en el botón Ignorar. he sugerido ejecutar EnumWindows en un hilo separado; utilicé FindWindow en su lugar.

Esta es la función que encuentra el mensaje emergente Assert, encuentra el botón Ignorar allí y luego hace clic en él. Se va en un bucle que comprueba una variable global cada vez (fea pero rápido):

void CloseAssertBox (void *param) { 
    HWND window, button; 
    Sleep (200); //wait 200 milliseconds 
    while (!finishThread) { //see if we can stop checking 
    if ((window = FindWindow (NULL, L"Microsoft Visual C++ Runtime Library")) 
     && (button = FindWindowEx (window, NULL, L"Button", L"&Ignore"))) 
     SendMessage (button, BM_CLICK, 0, 0); //click the button 
    Sleep (50); //then check every 50 milliseconds 
    } 
} 

El título del cuadro de Assert podría ser diferente. Si se hace referencia a su botón Ignorar de manera diferente, puede usar EnumChildWindows para obtener el nombre de cada control secundario, incluidos los botones.

Antes del bit de código que aparece la afirmación, inicio un nuevo hilo que llama a la función anterior.

finishThread = 0; //this is set to 1 when the thread should finish 
_beginthread (CloseAssertBox, 0, NULL); //begin the thread 

Después de lo que es a través del código aserción propensas peligroso, puse:

finishThread = 1; //done threaded stuff 

De esta manera el hilo se cerrará la próxima vez alrededor de su bucle. Probablemente haya mejores formas de hacerlo.

he tenido que incluir estas bibliotecas para hacer que funcione:

#include <process.h> //for multithreading 
#include <WinBase.h> //for Sleep function 
int finishThread; //to tell the thread when encoding has finished 

Todo esto fue hecho en Visual Studio 2010 utilizando una biblioteca de 2006.

Cuestiones relacionadas