How can I get URLs of open pages from Chrome and Firefox?
It's specific for every browser. That's for the major ones:
- Internet Explorer - You can use SHDocVw (like you did)
- Firefox - You can get the URL using DDE (source below)
- Chrome - You can get the URL while enumerating all the child windows untill you get to the control with class "Chrome_OmniboxView" and then get the text using
GetWindowText
- Opera - You can use the same thing as Firefox, but with "opera"
- Safari - There is no known method since it uses custom drawn controls
EDIT: Since 2014, Chrome has changed and you need to get the URL with Acessibility.
Code to get the URL from Firefox/Opera using DDE (which used NDDE - the only good DDE wrapper for .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; }}
Using UIAutomation - get urls for FireFox and 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.Element, Condition.TrueCondition)) { if (ii.Current.LocalizedControlType == "edit") { if (!ii.Current.BoundingRectangle.X.ToString().Contains("empty")) { ValuePattern activeTab = ii.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern; var activeUrl = activeTab.Current.Value; return activeUrl; } } } } } }
Maybe this code can help something;Thanks to BLEZ for share this code. I use this code to capture unique addresses from firefox and add them to a listbox. But I think this is not for Chrome right?
(you Should add NDde.dll to your project, to do this go to solution explorer right click to References-> add Reference->Browse-> find that DLL (http://ndde.codeplex.com/ from binary folder.))
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")); } } }}