0

I feel very stupid and newb about this, but nowhere can I find any insights on what I'm experiencing. If this question has been asked or answered already, please send a link - the answer escapes me.

Referencing an S.O. Article regarding UI Automation and MSEdge I posted a while ago, I am able to route my way through some things, but I have come across a really strange phenomenon that I simply cannot explain.

I developed a routine that is marvelous at finding most of the Apps/Windows that I need, but it fails HARD when searching for Microsoft Edge, with a unique exception to this. . .

The routine snip outlined below will only be called if I cannot find it using other methods. In this method however, if I send a string in titleCaption that I have personally typed out as "*Microsoft Edge*" it will fail to find Microsoft Edge no matter what, in spite of the Debug.Print line below showing the text Microsoft Edge in the rootwinds(a).Current.Name!!

rootwinds = AutomationElement.RootElement.FindAll(TreeScope.Children, New PropertyCondition(AutomationElement.LocalizedControlTypeProperty, windowType(windowType_Int)))
For a = 0 To rootwinds.Count - 1
  Debug.Print(rootwinds(a).Current.Name)

  If rootwinds(a).Current.Name Like titleCaption Then
    app2Find = rootwinds(a)
  ElseIf rootwinds(a).Current.Name.Contains(titleCaption.Replace("*", "")) Then
    app2Find = rootwinds(a)
  End If
Next

The ONLY way I am able to have this method find Microsoft Edge is if I take the Debug.Print output from the Immediate window . . . copy it, and paste it into the place I'm specifying this string. . . then magically, it finds it. I do NOT understand.

The strings in this example LOOK IDENTICAL to these eyes:

Let's play "Spot the difference" level 10,000. . .

In this example, the red underlined string is the Typed version, and the green underlined is the copied/pasted version directly from the Immediate window. . . The Function FindApp is a Boolean Function that returns True when either the IntPtr Handle or AutomationElement (first 2 Param's) are Not Nothing . . . The first iteration returns False. . . the second returns True (I put them both in an And If statement to show their likeness to one another - normally the function is called once. . . Additionally, the code for pulling the Handle etc. is not the part that fails - I have isolated it to this instance.) This is an example of where I find the text in the Immediate Window.

SEE?  It's RIGHT THERE - but String Comparisons do not pick it up. . .

This issue also happens with other strings I am pulling from MSEdge like the string of the sign-in options. . . I can see the text plain as day but cannot get a match without using the results from Immediate window.

Do you see what I see?

Above is another example of the Immediate Window where I can get this text, but only after seeing it in the Immediate window and copying/pasting.

To make this even stranger . . . this method works fine for finding any other app/window I need. . . just not MSEdge.

I get the phenomenon when using Imports.System.Windows.Automation as well as using the UIAComWrapper.dll located here on GitHub using NuGet. Visual Studio is VS 2019 Professional, laptop is Windows 10.

k1dfr0std
  • 379
  • 1
  • 15
  • There's probably a Zero Width Space char (`\u200B`) after the `f` in `Microsoft`, then the default white space (`\u0032`) – Jimi Jul 23 '22 at 14:23
  • Okay, but wouldn't using the `*` wild card and the `like` operator account for that, or do I need to treat this like `regex` when looking for this information? Would it be better to use a `regex find` method instead? – k1dfr0std Jul 23 '22 at 14:33
  • You could search for just `" Edge"` as the Element's `Name` or use the `ClassName` instead. Or cross-check both values. – Jimi Jul 23 '22 at 14:33
  • The problem is is that it doesn't just fail for finding the window, it also fails for finding text that matches within the page itself too, most likely for the same reason... At least I'm assuming... And again so far, this only seems to happen in the Microsoft edge... – k1dfr0std Jul 23 '22 at 14:34
  • Maybe I could encode both strings in a different language, or perhaps encode it for URLs, and visually see what the difference is that way. If it is a zero width space, that would make sense as to why it's programmatically a different value... But then that would also mean they are using these all over the place and not just in the title of a tab or other control – k1dfr0std Jul 23 '22 at 14:42
  • I don't know how the VB.Net `Like` operator works - in details - and it's not supported in .Net Core. I don't usually count on localizable text to identify or track Windows / Elements. – Jimi Jul 23 '22 at 14:42
  • This article would be much easier to implement. I'm grabbing a bite to eat, but will implement this on the string supplied by `UI Automation` and see if that solves it. I never thought of checking the length of the text since I'm expecting it to be different lengths than my search query. https://stackoverflow.com/questions/24942167/simplest-way-to-get-rid-of-zero-width-space-in-c-sharp-string – k1dfr0std Jul 23 '22 at 14:53
  • I also no longer suspect it being VB.Net or the `UI automation` platform either but rather good old Microsoft... They are notorious for doing this stuff, like they did in the `WMIC` console... – k1dfr0std Jul 23 '22 at 15:03
  • 1
    You get the same result if you call `EnumWindows()` + `GetWindowTextLength()` + `GetWindowText()` -- BTW, I forgot to *localize* char 32 to hexadecimal: I wrote `\u0032` instead of `\u0020` :) -- Don't rely on localizable text, too many nuances. – Jimi Jul 23 '22 at 17:05
  • @Jimi, can you post an answer referencing these couple of articles with a good mention of using `Regex.Replace` to resolve? https://stackoverflow.com/questions/32371442/how-to-identify-zero-width-character https://stackoverflow.com/questions/32013346/zero-width-space-character-in-string-literals-detect-and-or-prevent Doesn't have to be `VB.Net` - can be `C#` since those can be converted. . . Would rather give you the credit since I would have NEVER thought of the `Zero Width Space` without your guidance - you deserve the prize. Put in a `Regex.Replace` for that char. on the `.Name` ~Fin – k1dfr0std Jul 24 '22 at 07:35
  • Post the answer yourself. I cannot post answers for now. – Jimi Jul 24 '22 at 13:22

1 Answers1

0

1000 thanks go to user Jimi (from the comments in my question) for the suggestion the issue may be zero width spaces.

Doing some research on this topic specifically led me to find these 3 S.O. articles:

Simplest way to get rid of zero-width-space in c# string

How to identify zero-width character?

Zero Width Space character in string literals: Detect and/or prevent

Turns out the character u\200B as described by Jimi was the problem. Using similar approaches (and learning this character is detectable in Regex search queries, I've decided to search the control data I'm querying with Regex as follows:

If Regex.Replace(ControlFound.Current.Name,"\u200B","").Contains(titleCaption.Replace("*","") Or Regex.Replace(ControlFound.Current.Name,"\u200B","") Like titleCaption Then
  'Do something here
End if

k1dfr0std
  • 379
  • 1
  • 15