Question

I am trying to get URL from Opera browser, I assumed it is the same as for Chrome but I was wrong since it doesn't work this way.

whatever I have done so far is:

    public static string GetURL(IntPtr intPtr, string programName, out string url)
    {
        string temp = null;
            if (programName.Equals("opera"))
        {
        //    // there are always multiple opera processes, so we have to loop through all of them to find the
        //    // process with a Window Handle and an automation element of name "Address and search bar"
          /*  string x = "";
            DdeClient dde = new DdeClient("opera", "WWW_GetWindowInfo");
            try
            {
                //temp := RequestData('0xFFFFFFFF');
                dde.Connect();
                string url1 = dde.Request("URL", int.MaxValue);
                string[] text = url1.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
                dde.Disconnect();
            }
            catch (Exception)
            {
                x = "failed";
             }
*/



            Process[] procsOpera = Process.GetProcessesByName("opera");
            foreach (Process opera in procsOpera)
            {
                // the chrome process must have a window
                if (opera.MainWindowHandle == IntPtr.Zero)
               {
                      continue;
                }

                // find the automation element
                AutomationElement elm = AutomationElement.FromHandle(opera.MainWindowHandle);
                AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants,
                  new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));

                // if it can be found, get the value from the URL bar
                if (elmUrlBar != null)
                {
                    AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns();
                    if (patterns.Length > 0)
                    {
                        ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0]);
                        temp = val.Current.Value.ToString();
                        url = val.Current.Value.ToString();
                    }
                    else
                    {
                        temp = "";
                        url = "";
                    }
                }
                else
                {
                    temp = "";
                    url = "";
                }
            }
        }
        url = temp;
        return temp;
    }

I have tried it with both NDDE client and automation element, but both are failed :( I think in automation element the problem is in this line

AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));

Perhaps for opera it isn't "Address and search bar" can some 1 help me to solve the issue please?

NOTE: There are couple question where chrome and opera tagged but there is no Opera working answer inside on SO.

Était-ce utile?

La solution

You can use Inspect which offers the same functionality as UISpy to get the AutomationId from the Opera UI. I assume the reason it is not working is because it is named differently in Opera.

Autres conseils

You can download the NDde dll. After adding a reference simply just copy this code to where you want to get the url.

NDde DLL Download : http://ndde.codeplex.com/

DdeClient dde = new DdeClient("opera", "WWW_GetWindowInfo");
dde.Connect();
string url = dde.Request("URL", int.MaxValue);
string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
dde.Disconnect();

If you want to get firefox data simply change the opera to firefox

DdeClient dde = new DdeClient("firefox", "WWW_GetWindowInfo");
dde.Connect();
string url = dde.Request("URL", int.MaxValue);
string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
dde.Disconnect();

In a function

private string GetBrowserURL(string browser) {
    try {
        DdeClient dde = new DdeClient(browser, "WWW_GetWindowInfo");
        dde.Connect();
        string url = dde.Request("URL", int.MaxValue);
        string[] text = url.Split(new string[] { "\",\"" }, StringSplitOptions.RemoveEmptyEntries);
        dde.Disconnect();
        return text[0].Substring(1);
    } catch {
        return null;
    }
}
  1. Get Process id for opera:

    public static void GetOperaURL()
    {
       Process[] OProcesses = Process.GetProcessesByName("opera");
       string url = null;
       foreach (Process proc in OProcesses)
       {
           if (proc.MainWindowHandle != IntPtr.Zero)
           {
                url = getOperaUrlFromProcess(proc);
                break;
            }
        }
    }

  2. Use automation element for determining URL

    private static string getOperaUrlFromProcess(Process proc) { // find the automation element AutomationElement elm = AutomationElement.FromHandle(proc.MainWindowHandle); // manually walk through the tree, searching using TreeScope.Descendants is too slow (even if it's more reliable) AutomationElement elmUrlBar = null; try { var elm1 = elm.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Browser container")); if (elm1 == null) { return null; } elmUrlBar = elm.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address field")); } catch { // Chrome has probably changed something, and above walking needs to be modified. :( // put an assertion here or something to make sure you don't miss it return null; } // make sure it's valid if (elmUrlBar == null) { // it's not.. return null; } // there might not be a valid pattern to use, so we have to make sure we have one AutomationPattern[] patterns = elmUrlBar.GetSupportedPatterns(); if (patterns.Length == 1) { string ret = ""; try { ret = ((ValuePattern)elmUrlBar.GetCurrentPattern(patterns[0])).Current.Value; } catch { } if (ret != "") { return ret; } return null; } return null; }

Changed your function and made it simple as possible. Works with the current Opera version 47.0

public static string GetOperaURL()
    {
        string url = "";

        Process[] procsOpera = Process.GetProcessesByName("opera");
        foreach (Process opera in procsOpera)
        {
            // the chrome process must have a window
            if (opera.MainWindowHandle == IntPtr.Zero)
            {
                continue;
            }

            // find the automation element
            AutomationElement elm = AutomationElement.FromHandle(opera.MainWindowHandle);
            AutomationElement elmUrlBar = elm.FindFirst(TreeScope.Descendants,
                new PropertyCondition(AutomationElement.NameProperty, "Address field"));

            // if it can be found, get the value from the URL bar
            if (elmUrlBar == null) continue;

            AutomationPattern pattern = elmUrlBar.GetSupportedPatterns().FirstOrDefault(wr=>wr.ProgrammaticName == "ValuePatternIdentifiers.Pattern");

            if (pattern == null) continue;

            ValuePattern val = (ValuePattern)elmUrlBar.GetCurrentPattern(pattern);
            url = val.Current.Value;
            break;
        }

        return url;
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top