Необработанное исключение типа «System.ExecutionEngineException», возникающее при попытке прочитать окно из GetWindowText() из user32.dll

В моем приложении я читаю текст окна для того же процесса. Я использую GetWindowText из User32.dll. Но когда он пытается вызвать метод, я получаю исключение «Необработанное исключение типа« System.ExecutionEngineException »произошло в aaaa.exe». Где я могу увидеть точную ошибку. И почему я получаю это исключение.

Мой код, как показано ниже.

[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern int GetWindowText(IntPtr hWnd, 
    [Out] StringBuilder lpString, int nMaxCount);

EnumDelegate enumfunc = new EnumDelegate(EnumWindowsProc);

private bool EnumWindowsProc(IntPtr win, int lParam)
{
    StringBuilder sb = new StringBuilder();
    GetWindowText(win, sb, 100);
    if (sb.Length > 0)
    {
        // do something
    }
}

person Nayana Setty    schedule 06.01.2010    source источник
comment
Не могли бы вы показать нам (уменьшенный) образец, демонстрирующий исключение? Возможно, это связано с тем, как вы вызываете GetWindowText. Поскольку вы хотите прочитать текст из окна того же процесса, почему бы вам вместо этого не использовать управляемый API?   -  person Dirk Vollmar    schedule 06.01.2010
comment
@AvidProgrammer: ваш код отличается от образца nobugz. Вам не хватает инициализации StringBuilder с начальной емкостью и передачи именно этой емкости в качестве значения `nMaxCount` функции GetWindowText. Это должно делать свое дело. Если вы этого не сделаете, ваш объект построителя строк имеет пустой буфер, и GetWindowText не сможет записать в него (и в качестве побочного узла для будущих публикаций: сделайте отступ в коде на 4 пробела или нажмите Форматировать как код кнопка, которая сделает код красиво отформатированным).   -  person Dirk Vollmar    schedule 07.01.2010
comment
@divo: Спасибо, что указали на разницу. Установка емкости построителя строк и отправка ее в функцию API сделали свое дело.   -  person Nayana Setty    schedule 07.01.2010


Ответы (1)


Вы получаете это исключение, потому что ваш вызов GetWindowText() повредил кучу собранного мусора. Это легко сделать, если вы передаете строку вместо StringBuilder или забыли инициализировать StringBuilder.

Правильный путь:

  [DllImport("user32.dll", CharSet = CharSet.Unicode)]
  private static extern bool GetWindowText(IntPtr hWnd, StringBuilder buffer, int buflen);
...
  var sb = new StringBuilder(666);
  if (GetWindowText(handle, sb, sb.Capacity)) {
    string txt = sb.ToString();
    //...
  }
person Hans Passant    schedule 06.01.2010
comment
Я использую построитель строк и также инициализировал его. Единственное изменение заключается в том, что я использую кодировку как CharSet.Auto. Будет ли это проблемой? - person Nayana Setty; 06.01.2010
comment
У вас есть ссылка на ваше последнее заявление? Я успешно использовал GetWindowText для получения заголовка внепроцессных HWND и в соответствии с разделом примечаний здесь (msdn.microsoft.com/en-us/library/ms633520%28VS.85%29.aspx) это тоже не должно быть проблемой. - person Dirk Vollmar; 06.01.2010
comment
Только этот: Эта функция не может получить текст элемента управления редактирования в другом приложении. Я обновлю свой пост, спасибо. - person Hans Passant; 06.01.2010
comment
@nobugz: Извините, я пропустил эту часть документации. Я использовал GetWindowText только для получения заголовка главного окна другого приложения, что не проблема. Спасибо за подсказку! - person Dirk Vollmar; 07.01.2010