c# 从所有选项卡中获取 Chrome URL
c# Getting Chrome URL's from all tab
嗨,我想从浏览器获取 URL,对于 chrome,我使用了这些,但无法正常工作,我认为 chrome 已经改变了一些东西。 elm4 == null.
我使用 UIAutomation 进行了更多搜索,但所有示例均无效...
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;
}
}
}
此代码对我有效并获得 chrome
的活动选项卡的 URL
Process[] procsChrome = Process.GetProcessesByName("chrome");
foreach (Process chrome in procsChrome)
{
// the chrome process must have a window
if (chrome.MainWindowHandle == IntPtr.Zero)
{
continue;
}
// find the automation element
AutomationElement elm = AutomationElement.FromHandle(chrome.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]);
Console.WriteLine("Chrome URL found: " + val.Current.Value);
listbox.Items.Add(val.Current.Value);
}
}
}
我最近用 System.Windows.Forms.SendKeys 解决了同样的问题
与您的结果相比 - 它快 4 倍,但不适用于使用 ctrl+l 热键的网站(例如编辑模式下的 StackOwerflow)。
取决于您的需求:)
public void WithSendkeys()
{
AutomationElement.RootElement
.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1"))
.SetFocus();
SendKeys.SendWait("^l");
var elmUrlBar = AutomationElement.FocusedElement;
var valuePattern = (ValuePattern) elmUrlBar.GetCurrentPattern(ValuePattern.Pattern);
Console.WriteLine(valuePattern.Current.Value);
}
代码如下:
AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
Condition condNewTab = new PropertyCondition(AutomationElement.NameProperty, "Novo separador");
AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, condNewTab);
TreeWalker treewalker = TreeWalker.ControlViewWalker;
// IF THROWS A ERROR HERE, LOOK AT THE AutomationElement.NameProperty ("Novo separador") - PUT THIS TEXT IN APROPRIATE LANGUAGE
AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab);
Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem);
foreach (AutomationElement tabitem in elmTabStrip.FindAll(TreeScope.Children, condTabItem))
{
// HERE IS YOUR TABS!!!!
ret.Add(tabitem.Current.Name);
}
嗨,我想从浏览器获取 URL,对于 chrome,我使用了这些,但无法正常工作,我认为 chrome 已经改变了一些东西。 elm4 == null.
我使用 UIAutomation 进行了更多搜索,但所有示例均无效...
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;
}
}
}
此代码对我有效并获得 chrome
的活动选项卡的 URL Process[] procsChrome = Process.GetProcessesByName("chrome");
foreach (Process chrome in procsChrome)
{
// the chrome process must have a window
if (chrome.MainWindowHandle == IntPtr.Zero)
{
continue;
}
// find the automation element
AutomationElement elm = AutomationElement.FromHandle(chrome.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]);
Console.WriteLine("Chrome URL found: " + val.Current.Value);
listbox.Items.Add(val.Current.Value);
}
}
}
我最近用 System.Windows.Forms.SendKeys 解决了同样的问题 与您的结果相比 - 它快 4 倍,但不适用于使用 ctrl+l 热键的网站(例如编辑模式下的 StackOwerflow)。 取决于您的需求:)
public void WithSendkeys()
{
AutomationElement.RootElement
.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1"))
.SetFocus();
SendKeys.SendWait("^l");
var elmUrlBar = AutomationElement.FocusedElement;
var valuePattern = (ValuePattern) elmUrlBar.GetCurrentPattern(ValuePattern.Pattern);
Console.WriteLine(valuePattern.Current.Value);
}
代码如下:
AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
Condition condNewTab = new PropertyCondition(AutomationElement.NameProperty, "Novo separador");
AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, condNewTab);
TreeWalker treewalker = TreeWalker.ControlViewWalker;
// IF THROWS A ERROR HERE, LOOK AT THE AutomationElement.NameProperty ("Novo separador") - PUT THIS TEXT IN APROPRIATE LANGUAGE
AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab);
Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem);
foreach (AutomationElement tabitem in elmTabStrip.FindAll(TreeScope.Children, condTabItem))
{
// HERE IS YOUR TABS!!!!
ret.Add(tabitem.Current.Name);
}