Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automation.AddAutomationPropertyChangedEventHandler calls freezes app #6

Open
vforvoid opened this issue Sep 10, 2015 · 10 comments
Open

Comments

@vforvoid
Copy link

It seems like calling this method makes my application freeze.
It is happening on Factory.AddPropertyChangedEventHandler call
https://github.com/JakeGinnivan/UIAComWrapper/blob/master/UIAComWrapper/Automation.cs#L127

Any ideas why is it happening and how I can fix it?
Thanks in advance.

@Tankatronic
Copy link

Hey vforvoid, I tried to replicate the issue in a small console application and I am able to call the method without the freezing you describe. Are you trying to subscribe to a specific AutomationElement? What TreeScope are you providing?

This is the code I compiled to test that method. If you are subscribing to a specific element that is giving you problems, try using this test app to subscribe to the element in question in place of the RootElement I was using. This application was run on a Windows 7 OS.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Automation;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            SubscribeToPropertyChanged();
        }

        public static void SubscribeToPropertyChanged()
        {
            try
            {
                // Subscribe to Property Changed
                Automation.AddAutomationPropertyChangedEventHandler(
                    AutomationElement.RootElement,
                    TreeScope.Children,
                    new AutomationPropertyChangedEventHandler(OnPropertyChanged),
                    AutomationElement.AutomationIdProperty);

                while (true)
                {
                    System.Threading.Thread.Yield();
                }

            }
            catch (ElementNotAvailableException) { }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        private static void OnPropertyChanged(object sender, AutomationPropertyChangedEventArgs e)
        {
            return;
        }
    }
}

@vforvoid
Copy link
Author

Hey Tankatronic. Many thanks for taking a look at it!

Seems like your code example works just fine. I've tried it on a couple of different applications elements without any problems. I made a project last week using outdated .NET wrapper for UIA, going to try to replace it with your wrapper in a day or two to see what happens and update you with results.

@vforvoid
Copy link
Author

Ok, sorry for making you wait. I think it is some threading probmels. Check out this modified snippet:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Automation;
using System.Windows;

namespace UIAComWrapperTest
{
    class Program
    {
        static AutomationElement element;
        static AutomationPropertyChangedEventHandler handler;
        static AutomationFocusChangedEventHandler focusHandler;

        static void Main(string[] args)
        {
            SubscribeToFocusChange();
        }

        public static void SubscribeToFocusChange()
        {
            focusHandler = new AutomationFocusChangedEventHandler(OnFocusChange);
            Automation.AddAutomationFocusChangedEventHandler(focusHandler);

            while (true)
            {
                System.Threading.Thread.Yield();
            }
        }

        private static void OnFocusChange(object src, AutomationFocusChangedEventArgs e)
        {
            try
            {
                System.Diagnostics.Debug.WriteLine("Focus changed");
                var newElement = src as AutomationElement;
                if (element != null && element == newElement)
                    return;
                element = newElement;
                InitializePropertyChanged();
            }
            catch (ElementNotAvailableException ex) 
            {
                Console.WriteLine(ex);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
        }

        public static void InitializePropertyChanged()
        {
            try
            {
                //element = AutomationElement.FromPoint(new Point(1400, 800));
                //element = AutomationElement.FromPoint(new Point(1200, 681));
                System.Diagnostics.Debug.WriteLine("Class: " + element.Current.LocalizedControlType);
                var patterns = element.GetSupportedPatterns();
                if (!patterns.Contains(ValuePattern.Pattern))
                    return;
                var valuePattern = (ValuePattern)element.GetCurrentPattern(ValuePattern.Pattern);
                var value = valuePattern.Current.Value;
                handler = new AutomationPropertyChangedEventHandler(OnPropertyChanged);
                // Uncomment task starting code to bypass freezes (maybe i should use task queue on the main thread instead?). It will lead to a bug when we're able to subscribe to the same element's event multiple times
                // So we should keep track of elements and properties subscriptions if we don't want to run into it. 
                // I think .NET vanilla wrapper had no such issue, but it's manageable.
                //Task.Factory.StartNew(() =>
                //{
                    // This will freeze unless called from separate thread. This wouldn't freeze in vanilla wrapper.
                    Automation.AddAutomationPropertyChangedEventHandler(
                        element,
                        TreeScope.Subtree,
                        handler,
                        ValuePattern.ValueProperty);
                    System.Diagnostics.Debug.WriteLine("Subscribed to cahnges");
                //}
                //);
            }
            catch (ElementNotAvailableException) { }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }

        public static void OnPropertyChanged(object sender, AutomationPropertyChangedEventArgs e)
        {
            var valuePattern = (ValuePattern)(sender as AutomationElement).GetCurrentPattern(ValuePattern.Pattern);
            var value = valuePattern.Current.Value;
            System.Diagnostics.Debug.WriteLine("New value: " + value);
        }
    }

}

@Tankatronic
Copy link

Hey vforvoid,

I will run your test to see if I experience the same issue the first monday of October. I am currently out of the country right now visiting one of our offices and won't have time until I return. Just wanted to let you know I won't leave you hanging.

@vforvoid
Copy link
Author

Good day. I wonder if you have any time now to take a look at this?

@JakeGinnivan
Copy link
Member

Did one of you want contributor rights to this project, I don't have time to maintain at the moment and more than happy to add others

@vforvoid
Copy link
Author

Thanks, I'm quite busy with my current project atm, but if I will end up changing UIAComWrapper's code, I will create pull request for sure.

@Tankatronic
Copy link

I am currently on vacation but will get back to you in a couple weeks when
I return.

On Wed, Oct 28, 2015, 3:25 AM vforvoid [email protected] wrote:

Thanks, I'm quite busy with my current project atm, but if I will end up
changing UIAComWrapper's code, I will create pull request for sure.


Reply to this email directly or view it on GitHub
#6 (comment)
.

@ivan-danilov
Copy link
Contributor

@vforvoid I've tried your code and it does not freeze for me. At least I see a lot of "Subscribed to cahnges" messages in the output...
You could also try to update package to the last version (just published) and see exactly where the freeze happened (VS should silently download library sources from github and allow to debug in the new version, as new package includes pdb).

@vforvoid
Copy link
Author

Hey, thanks, I'm out due to new year, will try to check it as soon as I get
to my pc
On Dec 29, 2015 07:45, "ivan-danilov" [email protected] wrote:

@vforvoid https://github.com/vforvoid I've tried your code and it does
not freeze for me. At least I see a lot of "Subscribed to cahnges" messages
in the output...
You could also try to update package to the last version (just published)
and see exactly where the freeze happened (VS should silently download
library sources from github and allow to debug in the new version, as new
package includes pdb).


Reply to this email directly or view it on GitHub
#6 (comment)
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants