简体   繁体   中英

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

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();
}

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM