Текст из значения свойства UIAutomation усечен до 4 КБ

Я использую UIAutomation из 32-битного приложения C++ в Windows 7, чтобы получить текстовое содержимое окон других процессов. Я заметил, что API всегда возвращает строки, усеченные ровно до 4096 символов, если текст в окнах длиннее этого. Это происходит как с вызовами GetCachedPropertyValue(), так и с вызовами GetCurrentPropertyValue() для идентификаторов свойств UIA_ValueValuePropertyId и UIA_LegacyIAccessibleValuePropertyId. Протестировано, среди прочего, на 32- и 64-битном Блокноте. Когда я получаю текст с помощью SendMessage и сообщений WM_GETTEXTLENGTH и WM_GETTEXT, возвращается полный неусеченный текст. (В настоящее время я использую это как обходной путь.)

Просматривая документацию, я нигде не могу найти упоминания об этом ограничении или о том, как его обойти, чего я ожидал бы, если бы усечение было задумано. Я нашел похожий вопрос в stackoverflow, но, по-видимому, усечение из-за отладчика Visual Studio, а не из-за API UIAutomation. Однако этот вопрос дает понять, что UIAutomation должен иметь возможность возвращать очень длинные тексты. Поиск проблемы в Google приводит к еще одному вопросу о stackoverflow, который также упоминается ограничение в 4096 символов, но, к сожалению, этот вопрос и любой возможный ответ удалены.

Возможно, свойства UIA_ValueValuePropertyId или UIA_LegacyIAccessibleValuePropertyId не подходят для использования, но мне не удалось найти лучшего.

Может ли кто-нибудь указать мне, что я делаю неправильно, или есть предложения, что я мог бы попробовать? Также приветствуются указатели на фрагменты документации, которые я явно пропустил.

ТИА


person Jeroen ter Hofstede    schedule 04.10.2019    source источник


Ответы (1)


Экспозиция значения приведена здесь для удобства, но имеет ограниченные возможности. Вместо этого вы должны использовать TextPattern. и это DocumentRange свойство. Это явно указано здесь. Из него вы можете использовать GetText(-1) для получения ваших данных.

Вы можете закодировать это так:

string GetText(AutomationElement ae)
{
    return (ae.GetCurrentPattern(TextPattern.Pattern) as TextPattern)?.DocumentRange.GetText(-1);
}   
person Orace    schedule 09.10.2019
comment
Спасибо за ответ и ссылку на документацию. Я собираюсь попробовать это. Это не объясняет, почему в данном случае более миллиона символы были возвращены - но, конечно, если не указано ограничение, все может случиться. - person Jeroen ter Hofstede; 09.10.2019
comment
Работает нормально, спасибо. Однако все еще нужен обходной путь для тех приложений, которые не реализуют интерфейс TextPattern - например, блокнот... - person Jeroen ter Hofstede; 16.10.2019