winforms
winforms copied to clipboard
System.Windows.Automation.InvokePattern.Invoke blocks on a menu item.
.NET version
7.0.403
Did it work in .NET Framework?
Yes
Did it work in any of the earlier releases of .NET Core or .NET 5+?
Don't know, it works in .NET Framework 4.6.2, but not in latest version of .NET Framework 4.8
Issue description
Run the unit test in the following solution. Notice that the unit test hangs on line 80 of UnitTest1.cs which is the InvokePattern.Invoke call on the FIle/Open... menu item. This makes it impossible to test any menu item using System.Automation?
Steps to reproduce
- on Windows 11 22H2 build 22621.2361
- Load this solution into VS 2022
- Run Test/Debug all tests
- wait for windows open file dialog to appear
- Notice it never disappears
- hit break in the debugger and you will see it is blocked on line 80 of UnitTest1.cs.
@Olina-Zhang can your team please test this to confirm?
@elachlan we can repro this issue on .NET 6.0, 7.0, 8.0 and 9.0.
[like] Chris Lovett reacted to your message:
I and @Amy-Li03 discussed this issue, and we think this is not a a11y issue.
@Epica3055 let's discuss in the next meeting.
@Amy-Li03 - Could you please verify if this issue reproduces on 4.7.2 and 4.8.1 and if it depends on any AccessibilityImprovements.Level?
Attached is a .NET Framework 4.7.2 version of the above test app and the test passes (the invoke does not block) WindowsFormsApp1.zip
If you then change the project properties to target .NET Framework 4.8, the test fails as per my original bug report.
@Tanya-Solyanik , this issue reproduces on .NET Framework 4.8 & 4.8.1 and it doesn't repro on 4.7.2 and its previous versions. Also it doesn't depend on AccessibilityImprovements.Level, add following quirk to app.config file, issue still repro.
<runtime>
<AppContextSwitchOverrides value="Switch.UseLegacyAccessibilityFeatures=false;Switch.UseLegacyAccessibilityFeatures.2=false;Switch.UseLegacyAccessibilityFeatures.3=false;Switch.UseLegacyAccessibilityFeatures.4=false;Switch.UseLegacyAccessibilityFeatures.5=false" />
</runtime>
.netFramwork4.7 project:
The function RawInvokePattern_Invoke(hobj)
return 0
UIAutomationClientsideProviders.dll!MS.Internal.AutomationProxies.Accessible.DoDefaultAction() Line 527 C#
UIAutomationClientsideProviders.dll!MS.Internal.AutomationProxies.MsaaNativeProvider.CallDoDefaultAction() Line 820 C#
UIAutomationClientsideProviders.dll!MS.Internal.AutomationProxies.MsaaNativeProvider.System.Windows.Automation.Provider.IInvokeProvider.Invoke() Line 515 C#
[Native to Managed Transition]
[Managed to Native Transition]
UIAutomationClient.dll!MS.Internal.Automation.UiaCoreApi.InvokePattern_Invoke(MS.Internal.Automation.SafePatternHandle hobj) Line 659 C#
netFramwork4.8.1 project:
The function RawInvokePattern_Invoke(hobj)
return -2146233083
UIAutomationClient.dll!MS.Internal.Automation.UiaCoreApi.CheckError(int hr) Line 1017 C#
UIAutomationClient.dll!MS.Internal.Automation.UiaCoreApi.InvokePattern_Invoke(MS.Internal.Automation.SafePatternHandle hobj) Line 660 C#
UIAutomationClient.dll!System.Windows.Automation.InvokePattern.Invoke() Line 28 C#
TestProject1.dll!TestProject1.UnitTest1.Invoke(System.Windows.Automation.AutomationElement e) Line 99 C#
TestProject1.dll!TestProject1.UnitTest1.InvokeMenuItem(System.Windows.Automation.AutomationElement window, string menuItemName) Line 91 C#
TestProject1.dll!TestProject1.UnitTest1.TestMethod1() Line 35 C#
@LeafShi1 - does 4.8.1 sample block as well?
@LeafShi1 - does 4.8.1 sample block as well?
Yes
@LeafShi1 - what other controls does this reproduce for?
@LeafShi1 - what other controls does this reproduce for?
- I tried this in a button, it work well. WindowsFormsApp9.zip
- Adding a ComboBox to the MenuStrip, execute Invoke on the ComboBox, it also work well.
- Changing the
fd.ShowDialog(this)
toMessageBox.Show("....."),
of the WinFormsApp1.zip project, then run the unit test, the Invoke is also blocked.
So this problem only reproduces in MenuStrip, and the invoke event of menuItem needs to pop up a new windows page.
@LeafShi1 - do we have any unit tests that call the Invoke method on controls? If not, could you please add some?
@LeafShi1 - do we have any unit tests that call the Invoke method on controls? If not, could you please add some?
Many controls contain an IsPatternSupported test but the Invoke method on the control is not tested? Do we need to complete all of them? Such as https://github.com/dotnet/winforms/blob/9313f05e84328c3176eb7d80497c9505cd8aaebf/src/System.Windows.Forms/tests/UnitTests/System/Windows/Forms/AccessibleObjects/HScrollBar.ScrollBarFirstLineButtonAccessibleObjectTests.cs#L128-L135
Start with the MenuItems mentioned in this bug and buttons, we'll see if we need to add more later.
Start with the MenuItems mentioned in this bug and buttons, we'll see if we need to add more later.
Try to add following test, the System.Windows.Forms.AccessibleObject.Invoke blocks on Button and MenuItem. But System.Windows.Automation.InvokePattern.Invoke only blocks on MenuItem.
{
int callCount = 0;
using Button button = new()
{
AccessibleRole = AccessibleRole.Default
};
button.CreateControl();
ButtonAccessibleObject buttonAccessibleObject = new(button);
button.Click += (sender, e) =>
{
MessageBox.Show("TestDialog");
callCount++;
};
buttonAccessibleObject.Invoke();
Assert.Equal(1, callCount);
foreach (Form form in Application.OpenForms)
{
if (form.Text == "TestDialog")
{
form.Close();
break;
}
}
}
This is interesting, my test application was blocking on a button. I was doing a cross process access though. I have a driver application and a test application, and the driver is invoking buttons in the test app.
Let's test only for menuitems for now. Going forward we can start replacing code that send clicks to buttons(or other controls) with AccessibleObject.Invoke in tests that excersize control functionality.
Well after waiting for almost a year I've given up waiting. I ended up implementing my own custom automation layer for my menu items so that I could invoke them asynchronously. This gets my unit tests back up and running finally. See this commit: https://github.com/microsoft/XmlNotepad/commit/484713b6bd527a27644109994c139f3dd007deb3 And specifically the HiddenMenuItems control that provides new custom AutomationObjects for my menu items with a feature that can invoke some of them asynchronously (specifically the ones that pop up a modal file open or save dialog).