web-dev-qa-db-fra.com

Comment puis-je obtenir les URL des pages ouvertes à partir de Chrome et de Firefox?

J'écris une application de la barre d'état système qui doit vérifier si une application Web interne est ouverte.

Je peux vérifier IE en utilisant les éléments suivants:

SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindows();
        string filename;
        bool sdOpen = false;
        foreach (SHDocVw.InternetExplorer ie in shellWindows)
        {
            filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower();
            if (filename.Equals("iexplore"))
            {
                string[] urlParts = (ie.LocationURL.ToString()).Split('/');
                string website = urlParts[2];
                if (website == "myApp:8080") { sdOpen = true; };
            }
        }

        if (sdOpen) { Console.WriteLine("App is open"); } else { Console.WriteLine("App is not open"); };

        Console.ReadKey(true);

Cependant, certains utilisateurs du système préfèrent Chrome ou Firefox.

Comment puis-je procéder comme indiqué ci-dessus (obtenir les URL de tous les onglets ouverts dans le navigateur) pour Chrome et Firefox? (Je ne vais pas m'embêter avec d'autres navigateurs, car ce sont les seuls utilisés dans notre organisation.)

22
Ben

C'est spécifique pour chaque navigateur. C'est pour les plus importants:

  • Internet Explorer - Vous pouvez utiliser SHDocVw (comme vous l'avez fait)
  • Firefox - Vous pouvez obtenir l'URL en utilisant DDE (source ci-dessous)
  • Chrome - Vous pouvez obtenir l'URL en énumérant toutes les fenêtres enfants jusqu'à ce que vous obteniez le contrôle avec la classe "Chrome_OmniboxView", puis le texte utilisant GetWindowText
  • Opera - Vous pouvez utiliser la même chose que Firefox, mais avec "opera"
  • Safari - Il n'y a pas de méthode connue car il utilise des contrôles dessinés personnalisés

EDIT: Depuis 2014, Chrome a changé et vous devez obtenir l'URL avec l'acessibilité.

Code pour obtenir l'URL de Firefox/Opera en utilisant DDE (qui utilisait NDDE - le seul bon wrapper DDE pour .NET):

//
// usage: GetBrowserURL("opera") or GetBrowserURL("firefox")
//

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;
    }
}
22
blez

Utilisation de UIAutomation - Obtenir les URL pour FireFox et Chrome:

 else if (browser == BrowserType.Chrome)
        {
            //"Chrome_WidgetWin_1"

            Process[] procsChrome = Process.GetProcessesByName("chrome");
            foreach (Process chrome in procsChrome)
            {
                // the chrome process must have a window
                if (chrome.MainWindowHandle == IntPtr.Zero)
                {
                    continue;
                }
                //AutomationElement Elm = AutomationElement.RootElement.FindFirst(TreeScope.Children,
                //         new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1"));
                // find the automation element
                AutomationElement Elm = AutomationElement.FromHandle(chrome.MainWindowHandle);

                // manually walk through the tree, searching using TreeScope.Descendants is too slow (even if it's more reliable)
                AutomationElement elmUrlBar = null;
                try
                {
                    // walking path found using inspect.exe (Windows SDK) for Chrome 29.0.1547.76 m (currently the latest stable)
                    var Elm1 = Elm.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Google Chrome"));
                    var Elm2 = TreeWalker.ControlViewWalker.GetLastChild(Elm1); // I don't know a Condition for this for finding :(
                    var Elm3 = Elm2.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, ""));
                    var Elm4 = Elm3.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar));
                    elmUrlBar = Elm4.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
                }
                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
                    continue;
                }

                // make sure it's valid
                if (elmUrlBar == null)
                {
                    // it's not..
                    continue;
                }

                // elmUrlBar is now the URL bar element. we have to make sure that it's out of keyboard focus if we want to get a valid URL
                if ((bool)elmUrlBar.GetCurrentPropertyValue(AutomationElement.HasKeyboardFocusProperty))
                {
                    continue;
                }

                // 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 != "")
                    {
                        // must match a domain name (and possibly "https://" in front)
                        if (Regex.IsMatch(ret, @"^(https:\/\/)?[a-zA-Z0-9\-\.]+(\.[a-zA-Z]{2,4}).*$"))
                        {
                            // prepend http:// to the url, because Chrome hides it if it's not SSL
                            if (!ret.StartsWith("http"))
                            {
                                ret = "http://" + ret;
                            }
                            return ret;
                        }
                    }
                    continue;
                }
            }

        }
        else if (browser == BrowserType.Firefox)
        {
            AutomationElement root = AutomationElement.RootElement.FindFirst(TreeScope.Children,
                new PropertyCondition(AutomationElement.ClassNameProperty, "MozillaWindowClass"));

                Condition toolBar = new AndCondition(
                new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ToolBar),
                new PropertyCondition(AutomationElement.NameProperty, "Browser tabs"));
                var tool = root.FindFirst(TreeScope.Children, toolBar);

                var tool2 = TreeWalker.ControlViewWalker.GetNextSibling(tool);

                var children = tool2.FindAll(TreeScope.Children, Condition.TrueCondition);

                foreach (AutomationElement item in children)
                {
                    foreach (AutomationElement i in item.FindAll(TreeScope.Children, Condition.TrueCondition))
                    {
                        foreach (AutomationElement ii in i.FindAll(TreeScope.Children, Condition.TrueCondition))
                        {
                            if (ii.Current.LocalizedControlType == "document")
                            {
                                if (!ii.Current.BoundingRectangle.X.ToString().Contains("Infinity"))
                                {
                                    ValuePattern activeTab = ii.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
                                    var activeUrl = activeTab.Current.Value;
                                    return activeUrl;
                                }
                            }
                        }
                    }
                }
            }
3
cablehead

Peut-être que ce code peut aider quelque chose; Merci à BLEZ pour partager ce code. J'utilise ce code pour capturer des adresses uniques de Firefox et les ajouter à une liste. Mais je pense que ce n'est pas pour Chrome non?

(Vous devez ajouter NDde.dll à votre projet. Pour ce faire, accédez à la solution Explorateur, cliquez avec le bouton droit de la souris sur Références-> ajouter une référence-> Parcourir-> recherchez que DLL ( http://ndde.codeplex.com/ du dossier binaire.))

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NDde.Client;

namespace WindowsFormsApplication9
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            timer1.Enabled = true;
        }

        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;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            int j=0;
            for (int i = 0; i < listBox1.Items.Count; i++)
            {
                if (listBox1.Items[i].ToString() == GetBrowserURL("Firefox"))
                {
                    break;
                }
                else
                {
                    j++;
                }
            }
            if (j == listBox1.Items.Count)
            {
                listBox1.Items.Add(GetBrowserURL("Firefox"));
            }
        }
    }
}
2
matasoy

Le code ci-dessous fonctionne plutôt bien avec Chrome Version 58.0.3029.110:

Veuillez ajouter les références de UIAutomationClient et UIAutomationProvider de Assembly fournies par .NET.

        foreach (Process proc in procsChrome)
        {
            // the chrome process must have a window 
            if (proc.MainWindowHandle == IntPtr.Zero)
                continue;

            // to find the tabs we first need to locate something reliable - the 'New Tab' button 
            AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
            var SearchBar = root.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.NameProperty, "Address and search bar"));
            if (SearchBar != null)
                return (string)SearchBar.GetCurrentPropertyValue(ValuePatternIdentifiers.ValueProperty);
        }
0
Kalyan Hurkat