2012-08-17 12 views
8

Mam ten fragment kodu:.NET 4.0 - AccessViolationException i WndProc

internal class MTool : NativeWindow 
{ 
    private const int WM_LBUTTONDOWN = 0x0201; 
    public event TipDeactivateEventHandler Deactivate; 

    protected override void WndProc(ref System.Windows.Forms.Message m) 
    {   
     if(m.Msg == WM_LBUTTONDOWN) 
     { 
      if(this.Deactivate != null) 
      { 
       this.Deactivate(); 
      } 
     } 

     base.WndProc(ref m); 
    } 
} 

Kiedy uruchomić mój program pojawia się błąd AccessViolationException na linii base.WndProc(ref m); i nie wiem dlaczego.

Wygląda na to, że został przeniesiony z .NET 2.0 na 4.0 i moja teoria mówi, że może istnieć alternatywna metoda używana teraz zamiast nadpisywania WndProc. Czy to przypadek? Jeśli nie, dlaczego otrzymuję ten wyjątek?

+0

Czy możesz podać bardziej kompletny przykład? Co najmniej pokazuje, jak tworzysz okno MTool i wyświetlasz je? Chcę się upewnić, że moja repro jest blisko twojej. – Tim

+0

Więc właściwie nie pokazujesz tego konkretnego miejsca, tylko tworzysz obiekt? Czy nie potrzebujesz wywoływać CreateHandle lub czegoś podobnego, aby NativeWindow był przydatny? – Tim

+0

Czy próbowałeś umieścić punkt przerwania na base.WndProc i sprawdzając, jaka jest wartość m, gdy zgłaszany jest wyjątek ... czy też działa dla jakiegoś m lub czy rzuca wyjątek przy pierwszym wywołaniu .. –

Odpowiedz

7

Naprawiłem go poprzez dodanie tego atrybutu powyżej metody:

[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions] 

Następnie wokół linii gdzie wystąpi wyjątek z try/catch. Znalazłem tę informację here.

+2

Czy nie byłoby lepiej ustalić przyczynę wyjątku i spróbować go rozwiązać? – MikeKulls

1

Dokumentacja dla WndProc pokazuje, że wymaga pełnego zaufania. czy próbowałeś tego? np .:

[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
internal class MTool : NativeWindow 
{ 
    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")] 
    protected override void WndProc(ref Message m) 
    { 
//... 
+0

Próbowałem, wciąż otrzymuję ten sam wyjątek. –

0

Podejrzewam, że w Twoim kodzie dzieje się coś większego. Na podstawie Twojego urywka, spróbuję:

  1. Skomentuj przesłonięcie WndProc, czy to nadal jest repro przez awarię gdzieś indziej?
  2. Spraw, aby WndProc wywoływał tylko "base.WndProc (ref msg)". Czy nadal pojawia się ten sam błąd? Co to jest callstack? Czy w twoim stosie jest jeszcze więcej kodu?
  3. Przy użyciu kodu ułamkowego, który występuje tylko wtedy, gdy WM_LBUTTONDOWN? Kiedy to rzuci ten wyjątek, co jest podpięte do tego dezaktywatora?

Jeśli nie można ich wypróbować, prawdopodobnie trzeba zaktualizować fragment kodu, aby lepiej wyjaśnić, co próbujesz zrobić.

+2

Zdecydowanie odradzam używanie HPCSEAttribute, aby rozwiązać ten problem. Prawdopodobnie dzieje się tak, że Twój kod zarządzany generuje wyjątek, lub istnieje wyjątek rozrządowy (w jaki sposób zbudowałeś ptrStruct?). Kiedy masz kodowanie i pomijanie kodu rodzimego, tracisz kontekst oryginalnego wyjątku i ostatecznie pojawiasz się jako coś, czego CLR nie myśli, że może złapać. Atrybut, który został oflagowany jako poprawna odpowiedź, jest prawdopodobnie różnicą, dlaczego tak działało, ale istnieje głębszy problem, który jest ukrywany. Naprawdę powinieneś debugować to bardziej. –