Come posso ottenere URL di pagine aperte da Chrome e Firefox?

Sto scrivendo un’app per la barra delle applicazioni che deve verificare se è aperta un’app interna web.

Posso controllare IE usando il seguente:

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

Tuttavia, alcuni utenti che utilizzano il sistema preferiscono Chrome o Firefox.

Come posso fare lo stesso di sopra (ad esempio ottenere gli URL di eventuali tabs aperte nel browser) per Chrome e Firefox? (Non ho intenzione di disturbare con altri browser in quanto questi sono gli unici in uso nella nostra organizzazione.)

È specifico per ogni browser. Questo è per i più importanti:

  • Internet Explorer : puoi usare SHDocVw (come hai fatto tu)
  • Firefox : puoi ottenere l’URL usando DDE (fonte di seguito)
  • Chrome : puoi ottenere l’URL durante l’enumerazione di tutte le windows figlio fino a quando non raggiungi il controllo con la class “Chrome_OmniboxView” e ottieni il testo utilizzando GetWindowText
  • Opera – Puoi usare la stessa cosa di Firefox, ma con “opera”
  • Safari : non esiste un metodo noto poiché utilizza controlli personalizzati

EDIT: dal 2014, Chrome è cambiato ed è necessario ottenere l’URL con accessibilità.

Codice per ottenere l’URL da Firefox / Opera usando DDE (che ha usato NDDE – l’unico buon wrapper DDE per .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; } } 

Usando UIAutomation: ottieni gli URL per FireFox e 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; } } } } } } 

Forse questo codice può aiutare qualcosa; Grazie a BLEZ per condividere questo codice. Uso questo codice per acquisire indirizzi unici da firefox e aggiungerli a una listbox. Ma penso che questo non sia per Chrome, giusto?

(Dovresti aggiungere NDde.dll al tuo progetto, per farlo vai a solution explorer clicca col tasto destro su References-> aggiungi Reference-> Browse-> trova quella DLL ( http://ndde.codeplex.com/ dalla cartella binary.) )

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

Sotto il codice funzionano abbastanza bene con la versione 58.0.3029.110 di Chrome:

Aggiungi riferimento a UIAutomationClient e UIAutomationProvider dall’Assembly fornito da .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); }