2010-11-10 14 views
6

Mam następujący problem: Używam biblioteki C++ z mojej aplikacji WPF, biblioteka zgłasza asercję w bardzo rzadkich przypadkach. Pokazuje ładne okno dialogowe z plikiem C++, numerem linii i wyrażeniem assert. Pytanie brzmi: czy mogę wyłączyć pliki w bibliotece C++, zakładając, że nie mam kodu źródłowego. Naprawdę potrzebuję "złapać" to stwierdzenie i zalogować się.Czy można wyłączyć C++ z aplikacji .net

Dzięki.

+0

Czy to wyzwalanie twierdzenie lub rzuca wyjątek? – Ferruccio

+0

jest to stwierdzenie. Wyjątek nie jest problemem. –

Odpowiedz

1

W zależności od umiejętności asemblera i tego, czy kroki zostały celowo podjęte w celu zablokowania tego typu rzeczy, zazwyczaj można zmodyfikować kod binarny, aby zapobiec wyświetlaniu tego rodzaju wiadomości.

Jednak ostrzał asertywny jest często prekursorem bardziej spektakularnego wypadku lub innego niewłaściwego zachowania, więc samo zatrzymanie okna komunikatu może cię znacznie zająć. Oczywiście niektóre twierdzenia są błędne, więc może to być wszystko, czego potrzebujesz.

Gdybym musiał zmodyfikować tę bibliotekę DLL, zdemontowałem ją z IDA i opracowałem łatkę. Ukrywanie tego stwierdzenia byłoby prawdopodobnie dość łatwe, a rejestrowanie go o wiele trudniejsze.

3

Jednym ze sposobów jest utworzenie wątku, który wykonuje co pewien czas EnumWindows i wykrywa, czy pojawi się okno potwierdzenia, może je przechwycić i kliknąć przycisk Ignoruj. To nadal będzie powodować okna, aby pokazać się na krótki czas (w zależności od odstępu między EnumWindows ale zakładam, że klienci nie będą coraz DLL debugowania, więc nie powinno mieć znaczenia.


Another opcja dzwoni _CrtSetReportMode(_CRT_ASSERT, 0) wyłączyć twierdzi, ze pokazane są w ogóle. Jeśli chcesz pinvoke to z .NET zauważyć, że _CRT_ASSERT jest równa 2.

+1

Problem polega na tym, że biblioteka dll została opracowana przez inny zespół i działa w trybie zwolnienia :) dlatego szukam sposobu, aby to zatrzymać. –

+0

@Alex, dodałem kolejną opcję, która według mnie lepiej zaspokoi Twoje potrzeby. – Motti

+0

Motti, dzięki za pomysł. Spróbowałem, że to nie działa. Przypuszczam, że asercja jest spowodowana przez makra assert, ale twoje rozwiązanie działa z _ASSERT. Wygląda na to, że makro assert wyskakuje tylko okno dialogowe z informacją o potwierdzeniu :( –

0

niedawno miałem naprawić niektóre starego kodu, który oparł się na DLL, który czasem pojawiło up asertywna wiadomość.Próbowałem wszystkie powyższe sugestie, a jedyną, nad którą pracowałem było kliknięcie przycisku Ignore. ve zaproponował uruchomienie EnumWindows w osobnym wątku - zamiast tego użyłem FindWindow.

Jest to funkcja, która znajduje komunikat popup Assert, znajduje przycisk Ignoruj ​​w tym miejscu, a następnie klika go. To idzie w pętli, która sprawdza zmienną globalną za każdym razem (brzydki, ale szybki):

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 
    } 
} 

Tytuł skrzynce Assert może być inna. Jeśli Twój przycisk Ignoruj ​​ma inne odniesienia, możesz użyć EnumChildWindows, aby uzyskać nazwę każdego elementu sterującego podrzędnego, łącznie z przyciskami.

Przed bitem kodu, który pojawia się w assert, uruchamiam nowy wątek, który wywołuje powyższą funkcję.

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

Po wprowadzeniu go przez niebezpieczne assert podatne kodzie, ustawić:

finishThread = 1; //done threaded stuff 

ten sposób wątek zostanie zamknięty następnym razem runda jej pętli. Prawdopodobnie istnieją lepsze sposoby na zrobienie tego.

miałem do uwzględnienia tych bibliotek, aby to działało:

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

To wszystko było zrobione w Visual Studio 2010 przy użyciu biblioteki od 2006

Powiązane problemy