Я пытаюсь разработать библиотеку, которая позволяет тестировать пользовательский интерфейс приложения с помощью неуправляемого API UIAutomation от Microsoft. Мне трудно решить проблему реализации, связанную с доступом к элементам из других потоков, таких как обработчики событий. Я использую Interop DLL для доступа к UIAutomation, поэтому инициализация API выглядит следующим образом: static public IUIAutomation automation = new CUIAutomation();
.
Например: я подписываюсь на событие открытия окна:
automation.AddAutomationEventHandler(UIA_EventIds.UIA_Window_WindowOpenedEventId, automation.GetRootElement(), TreeScope.TreeScope_Subtree, null, this);
тогда, когда я вызываю кнопку в каком-то случайном приложении WinForms, которое открывает диалоговое окно, я попадаю внутрь HandleAutomationEvent(IUIAutomationElement sender, int eventId)
, где я хотел бы получить доступ к кнопке «ДА» в диалоге с помощью
sender.FindFirst(tree,MyClass.automation.CreatePropertyCondition(UIA_PropertyIds.UIA_NamePropertyId, "YES"));
Поиск занимает много времени, так как он не может получить доступ к COM-объекту из однопоточной квартиры. Я не могу получить подход из документации Microsoft для работы:
https://docs.microsoft.com/en-us/windows/desktop/winauto/uiauto-threading
Я пытался подписаться на события из других потоков, а также вызывать функции доступа к элементам, такие как FindAll
или FindFirst
, из других потоков с атрибутом [MTAThread]
, но я не могу заставить что-либо работать - эффект все тот же. Интересно, есть ли вариант, где элементы будут содержаться в MTA, даже если они не поточнобезопасны. Я абсолютный новичок в том, что касается C #, WinForms и COM-объектов, поэтому я был бы признателен за любую информацию, которая могла бы помочь.