Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetWindowText() throwing error and not being caught by try/catch

When I run the code below for the GetWindowText I get the following error thrown as an inner Exception:

{"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."}

    [DllImport("user32.dll", EntryPoint = "GetWindowTextLength", SetLastError = true)]
    internal static extern int GetWindowTextLength(IntPtr hwnd);

    [DllImport("user32.dll", EntryPoint = "GetWindowText", SetLastError = true)]
    internal static extern int GetWindowText(IntPtr hwnd, ref StringBuilder wndTxt, int MaxCount);

try{
      int strLength = NativeMethods.GetWindowTextLength(wndHandle);
      var wndStr = new StringBuilder(strLength);
      GetWindowText(wndHandle, ref wndStr, wndStr.Capacity);
   }
    catch(Exception e){ LogError(e) }

I have 2 questions:

  1. Why is the Error not being caught by the try catch?

  2. Any idea how I can stop the program crashing when it hits this type of error other than using try/catch

Cheers

like image 717
Neil_M Avatar asked Dec 20 '22 21:12

Neil_M


2 Answers

1.

There are some exceptions that cannot be caught. One type is StackOverflow or OutOfMemory because there is literally no memory to allocate for the handler to run. Another type is one delivered to the CLR via the windows OS. This mechanism is called structured exception handling. These kinds of exceptions can be very bad because the CLR cannot be sure that its own internal state is consistent and are sometimes called corrupted state exceptions. In .Net 4, managed code does not handle these exceptions by default.

The above message is from an AccessViolationException, which is a kind of corrupted state exception. This is happening because you are calling an unmanaged method which is writing past the end of a buffer. See this article on possibly handling these exceptions.

2.

Does the sample code here work? You need to make sure the unmanaged code doesn't write past the end of the StringBuilder's buffer.

public static string GetText(IntPtr hWnd)
{
    // Allocate correct string length first
    int length       = GetWindowTextLength(hWnd);
    StringBuilder sb = new StringBuilder(length + 1);
    GetWindowText(hWnd, sb, sb.Capacity);
    return sb.ToString();
}
like image 189
Mike Zboray Avatar answered Dec 23 '22 09:12

Mike Zboray


It's possible that calling these external methods is causing problems because of the parameters you're providing to GetWindowText. I think you should try the following:

try{
    int strLength = NativeMethods.GetWindowTextLength(wndHandle);
    var wndStr = new StringBuilder(strLength + 1);
    GetWindowText(wndHandle, wndStr, wndStr.Capacity);
   }
catch(Exception e){ LogError(e) }
like image 25
hatchet - done with SOverflow Avatar answered Dec 23 '22 11:12

hatchet - done with SOverflow