I am currently trying to use System.Windows.Automation
to automate a chrome instance, but at a certain point AutomationElement.FindAll(TreeScope.Children, Condition.TrueCondition);
returns always 0 children, but I can see them in inspect.exe. When I hit refresh in inspect.exe the elements show up in my app too.
While looking for a solution, I found this SO post, that OP had more or less the same issue. An answer suggested to use:
SystemParametersInfo( SPI_SETSCREENREADER, TRUE, NULL, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
PostMessage( HWND_BROADCAST, WM_WININICHANGE, SPI_SETSCREENREADER, 0);
I implemented that as:
[DllImport("user32.dll", SetLastError = true)]
static extern bool SystemParametersInfo(int uiAction, int uiParam, IntPtr pvParam, int fWinIni);
[DllImport("user32.dll")]
static extern bool PostMessage(IntPtr hWnd, uint Msg, int wParam, int lParam);
....
const int SPI_SETSCREENREADER = 0x0047;
IntPtr inptrnull = IntPtr.Zero;
const int SPIF_UPDATEINIFILE = 0x01;
const int SPIF_SENDCHANGE = 0x02;
IntPtr HWND_BROADCAST = new IntPtr(0xffff);
const int WM_WININICHANGE = 0x001A;
SystemParametersInfo(SPI_SETSCREENREADER, 1, inptrnull, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
PostMessage(HWND_BROADCAST, WM_WININICHANGE, SPI_SETSCREENREADER, 0);
But it has no effect.
What am I missing? Is there a other/better way to this?
Looks like you're using an obsolete managed UIA implementation (System.Windows.Automation). It's a known case when it could return not all of the children, it might be the cause.
As per the documentation:
You might try to use UIA COM interface instead (Inspect uses the same approach):
Add a reference to COM -> UIAutomationClient to your project. This will generate a wrapper for you, so the COM interface will be accessible in the code in a usual OO-style.
Create a UI Automation object and do your stuff with UIA elements:
If the above doesn't help, you might try to use RawTreeWalker instead of calling FindAll() to traverse the UI tree:
I've automated Chrome prevously using UIA and as far as I remember it might respond to UIA calls a bit odd: e.g. sometimes it returns a container element instead of the actual one (button, edit, etc). I resolved this case by doing several attempts until I finally retrieved what expected. What if you call FindAll() several times too?