C# 如何使用UI自动化激活Google Chrome选项卡项
我使用C#应用程序中的代码在Google Chrome中查找选项卡:C# 如何使用UI自动化激活Google Chrome选项卡项,c#,google-chrome,ui-automation,C#,Google Chrome,Ui Automation,我使用C#应用程序中的代码在Google Chrome中查找选项卡: Process[] procsChrome = Process.GetProcessesByName("chrome"); foreach (Process chrome in procsChrome) { // the chrome process must have a window if (chrome.MainWindowH
Process[] procsChrome = Process.GetProcessesByName("chrome");
foreach (Process chrome in procsChrome)
{
// the chrome process must have a window
if (chrome.MainWindowHandle == IntPtr.Zero)
{
continue;
}
AutomationElement root = AutomationElement.FromHandle(chrome.MainWindowHandle);
/*
Condition condNewTab = new PropertyCondition(AutomationElement.NameProperty, "Nueva pestaña");
AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, condNewTab);
// get the tabstrip by getting the parent of the 'new tab' button
TreeWalker treewalker = TreeWalker.ControlViewWalker;
AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab);
*/
// loop through all the tabs and get the names which is the page title
Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem);
foreach (AutomationElement tabitem in root.FindAll(TreeScope.Descendants, condTabItem))
{
Console.WriteLine(tabitem.Current.Name);
// I NEED TO ACTIVATE THE TAB HERE
break;
}
Condition condUrl = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit);
foreach (AutomationElement edit in root.FindAll(TreeScope.Descendants, condUrl))
{
string value = ((System.Windows.Automation.ValuePattern)edit.GetCurrentPattern(ValuePattern.Pattern)).Current.Value;
Console.WriteLine(value);
}
}
我需要使用UI自动化选择某些选项卡项。我该怎么做呢?我需要解决类似的问题。由于Chrome没有完全实现Windows自动化功能,因此必须以不同的方式实现 多亏了这个GitHub,我才能够激活正确的Chrome标签。诀窍是按下
Ctrl
+tab index
,在选项卡位置介于1和8之间时激活该选项卡(9个切换到最后一个选项卡,请参阅)。对于集合中进一步显示的选项卡,重复按Ctrl+选项卡
,直到达到所需的选项卡
然而,这并不是那么容易,因为有时选项卡会无序地出现在UI自动化集合中。我通过为每个选项卡调用TryGetClickablePoint
方法并根据返回点的X坐标对选项卡进行排序,解决了这个问题
bool ActivateChromeTab(string title)
{
Process[] procsChrome = Process.GetProcessesByName("chrome");
foreach (Process proc in procsChrome)
{
if (proc.MainWindowHandle == IntPtr.Zero)
{
continue;
}
AutomationElement root = AutomationElement.FromHandle(proc.MainWindowHandle);
Condition condNewTab = new PropertyCondition(AutomationElement.NameProperty, "New Tab");
AutomationElement elmNewTab = root.FindFirst(TreeScope.Descendants, condNewTab);
TreeWalker treewalker = TreeWalker.ControlViewWalker;
AutomationElement elmTabStrip = treewalker.GetParent(elmNewTab);
Condition condTabItem = new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.TabItem);
var index = 0;
var tabItems = elmTabStrip.FindAll(TreeScope.Children, condTabItem);
var coll = new List<AutomationElement>();
foreach (AutomationElement element in tabItems)
{
coll.Add(element);
}
bool NameMatch(string name)
{
return name == title || name.StartsWith(title + " ");
}
// short-circuit the search when no searched string cannot be found
if (!coll.Any(e => NameMatch(e.Current.Name)))
{
continue;
}
var t = new Stopwatch();
t.Start();
var withPoints = coll.AsParallel().Select(e =>
{
var point = new System.Windows.Point(int.MaxValue, int.MaxValue);
if (e.TryGetClickablePoint(out point))
{
}
return new
{
Name = e.Current.Name,
Element = e,
Point = point
};
}).OrderBy(e => e.Point.X);
foreach (var tabItem in withPoints)
{
index++;
var name = tabItem.Name;
if (NameMatch(name))
{
SetForegroundWindow(proc.MainWindowHandle); // activate window
Select(index); // select tab
return true;
}
}
}
return false;
}
bool ActivateChromeTab(字符串标题)
{
Process[]procsChrome=Process.getProcessByName(“chrome”);
foreach(程序中的过程程序)
{
if(proc.MainWindowHandle==IntPtr.Zero)
{
继续;
}
AutomationElement根=AutomationElement.FromHandle(proc.MainWindowHandle);
条件conditionnewtab=新属性条件(AutomationElement.NameProperty,“新选项卡”);
AutomationElement-Elmnetab=root.FindFirst(TreeScope.子孙,condnetab);
TreeWalker TreeWalker=TreeWalker.ControlViewWalker;
AutomationElement elmTabStrip=treewalker.GetParent(elmnetab);
Condition Condition TabItem=新属性Condition(AutomationElement.ControlTypeProperty,ControlType.TabItem);
var指数=0;
var tabItems=elmTabStrip.FindAll(TreeScope.Children,condTabItem);
var coll=新列表类)
[DllImport(“user32.dll”)]
私有静态外部无效keybd_事件(字节bVk、字节bScan、int-dwFlags、int-dwExtraInfo)
公共静态字节GetKeyNumber(整数)
{
如果(数字<0 | |数字>9)
抛出新的ApplicationException(“按键无效”);
返回(字节)(0x30+数字);
}
公共静态void KeyDown(字节vKey)
{
keybd_事件(vKey,0,KEYEVENTF_EXTENDEDKEY,0);
}
公共静态void KeyUp(字节vKey)
{
keybd_事件(vKey,0,KEYEVENTF_EXTENDEDKEY,KEYEVENTF_KEYUP,0);
}
公共静态无效按键(字节vKey)
{
KeyDown(vKey);
KeyUp(vKey);
}
公共静态字节LCtrl=0xA2;//VK\u LCONTROL
公共静态字节LWin=0x5B;//VK_LWin
公共静态字节LAlt=0xA4;//VK\u LMENU
公共静态字节Tab=0x09;//VK_Tab
private const int KEYEVENTF_EXTENDEDKEY=1;
private const int keyevent fu KEYUP=2;
对于那些仍在寻找答案的绝望的灵魂。以下是我的方法,完全基于UI Automation API,没有聚焦窗口和发送单击事件或热键。要使用下面的代码,您需要使用UIAutomationCore.dll的互操作参考,如所述
您需要记住的唯一一件事是,搜索最小化的Chrome窗口的选项卡是不可能的
public void Select(int tabIndex)
{
const int maxShortcutNumber = 8;
if (tabIndex <= 0) { return; }
KeyDown(LCtrl);
if (tabIndex <= maxShortcutNumber)
{
KeyPress(GetKeyNumber(tabIndex));
}
else
{
KeyPress(GetKeyNumber(maxShortcutNumber));
for (var i = 0; i < tabIndex - maxShortcutNumber; i++)
{
i.Dump();
const int timeToDigestPreviousKeyPress = 75;
Thread.Sleep(timeToDigestPreviousKeyPress);
KeyPress(Tab);
}
}
KeyUp(LCtrl);
}
public static byte GetKeyNumber(int number)
{
if (number < 0 || number > 9)
throw new ApplicationException("Invalid number for key press.");
return (byte)(0x30 + number);
}
public static void KeyDown(byte vKey)
{
keybd_event(vKey, 0, KEYEVENTF_EXTENDEDKEY, 0);
}
public static void KeyUp(byte vKey)
{
keybd_event(vKey, 0, KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
}
public static void KeyPress(byte vKey)
{
KeyDown(vKey);
KeyUp(vKey);
}
public static byte LCtrl = 0xA2; //VK_LCONTROL
public static byte LWin = 0x5B; //VK_LWIN
public static byte LAlt = 0xA4; //VK_LMENU
public static byte Tab = 0x09; //VK_TAB
private const int KEYEVENTF_EXTENDEDKEY = 1;
private const int KEYEVENTF_KEYUP = 2;
Process[] allChromeProcesses = Process.GetProcessesByName("chrome");
Process[] mainChromes = allChromeProcesses.Where(p => !String.IsNullOrEmpty(p.MainWindowTitle)).ToArray();
//...
//Here you need to check if you have found correct chrome instance
//...
var uiaClassObject = new CUIAutomation();
IUIAutomationElement chromeMainUIAElement = uiaClassObject.ElementFromHandle(mainChromes[0].MainWindowHandle);
//UIA_ControlTypePropertyId =30003, UIA_TabItemControlTypeId = 50019
IUIAutomationCondition chromeTabCondition = uiaClassObject.CreatePropertyCondition(30003, 50019);
var chromeTabCollection = chromeMainUIAElement.FindAll(TreeScope.TreeScope_Descendants, chromeTabCondition);
//UIA_LegacyIAccessiblePatternId = 10018, 0 -> Number of Chrome tab you want to activate
var lp = chromeTabCollection.GetElement(0).GetCurrentPattern(10018) as IUIAutomationLegacyIAccessiblePattern;
lp.DoDefaultAction();