Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用UI自动化激活Google Chrome选项卡项_C#_Google Chrome_Ui Automation - Fatal编程技术网

C# 如何使用UI自动化激活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

我使用C#应用程序中的代码在Google Chrome中查找选项卡:

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