问题 循环浏览chrome选项卡和关闭页面,具体取决于网址


我希望能够遍历chrome页面上的所有选项卡并关闭任何youtube页面的选项卡。

我做了一些谷歌搜索并找到了下面的代码。有两个(可能更多)问题。首先,我创建了一个WPF应用程序并添加了System.Windows.Automation命名空间(使用visual studio 2015 .net 4.5),但无法识别AutomationElement。

此外,我不确定如何循环选项卡并测试页面是否是youtube页面。

        Process[] procsChrome = Process.GetProcessesByName("chrome");

        if (procsChrome.Length <= 0)
            return null;

        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)
            {
                AutomationPattern[] patterns = SearchBar.GetSupportedPatterns();
                if(patterns.Length > 0)
                {
                    ValuePattern val = (ValuePattern)SearchBar.GetCachedPattern(patterns[0]);
                    if (val.Current.Value.Contains("youtube.com") || val.Current.Value.Contains("youtube.co.uk"))
                        proc.Close();
                }
            }
         }

11943
2018-01-25 16:00


起源

你有没有考虑过从另一个方向解决这个问题 - 比如安装 域名拦截器 以便youtube标签永远不会被打开? - Lynn Crumbling
@LynnCrumbling不,我们实际上没有打开youtube标签的问题。然而,在一段时间后(即人们离开办公室),任何youtube标签都会关闭 - mHelpMe
啊,所以你试图确保那些已经离开的员工没有通过流式传输视频来攫取带宽? - Lynn Crumbling
是的,就是这样! - mHelpMe


答案:


System.Windows.Automation在UIAutomationClient.dll中。您是否添加了UIAutomationClient.dll作为项目的参考?

检查值“youtube”。

if (SearchBar != null) 
{
    AutomationPattern[] patterns = SearchBar.GetSupportedPatterns();
    if (patterns.Length > 0) 
    {
        ValuePattern val = (ValuePattern)SearchBar.GetCurrentPattern(patterns[0]);
        if(val.Current.Value.Contains("youtube.com"))
            proc.Close();
    }
}

5
2018-01-25 17:32



我得到一个InvalidOperationException是未处理的errror。发生在UIAutomationClient.dll中。附加信息:不支持的模式。它发生在ValuePattern val =(ValuePattern).SearchBar.GetCurrentPattern(patterns [0]);线 - mHelpMe
如果调试行返回(字符串)SearchBar.GetCurrentPropertyValue(ValuePatternIdentifiers.ValueProperty);它确实返回了正确的网址,即此页面 - mHelpMe
然后检查该字符串值是否包含youtube.com,然后关闭proc。 - VK_217
@mHelpMe - 表示SearchBar元素不支持ValuePattern。事实上,根据我自己对最新版Chrome的研究,我认为不行。 url / adress的值不包含在元素中,而是包含在每个chrome窗口的全局的另一个元素中。我不认为你可以在没有先选择标签的情况下获得这个网址值,这会导致视觉上的闪烁 - Simon Mourier
@mHelpMe - 我尝试了各种各样的东西,但找不到合适的模式使用...不幸的是,Chrome是非常友好的UI自动化。大多数人使用selenium / webdriver来自动化chrome(或FF)。 - Simon Mourier


根据你的问题,我写了一个小程序来实现这个目标。如果有效,请告诉我。

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
class Program
{

    [DllImport("user32.dll")]
    static extern bool SetForegroundWindow(IntPtr hWnd);

    [DllImport("user32.dll")]
    static extern bool IsIconic(IntPtr hWnd);

    [DllImport("user32.dll")]
    static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

    static void Main()
    {
        Process[] procs = Process.GetProcessesByName("chrome");

        if (procs.Length == 0)
        {
            Console.WriteLine("Google Chrome is not currently open");
            return;
        }

        List<string> titles = new List<string>();

        IntPtr hWnd = IntPtr.Zero;
        int id = 0;
        int numTabs = procs.Length;

        foreach (Process p in procs)
        {
            if (p.MainWindowTitle.Length > 0)
            {
                hWnd = p.MainWindowHandle;
                id = p.Id;
                break;
            }
        }

        bool isMinimized = IsIconic(hWnd);

        if (isMinimized)
        {
            ShowWindow(hWnd, 9); // restore
            Thread.Sleep(100);
        }

        SetForegroundWindow(hWnd);
        SendKeys.SendWait("^1"); // change focus to first tab
        Thread.Sleep(100);

        int next = 1;
        string title;

        while (next <= numTabs)
        {
            try
            {
                title = Process.GetProcessById(id).MainWindowTitle.Replace(" - Google Chrome", "");
                if (title.ToLower().Contains("youtube"))
                {
                    SendKeys.SendWait("^{w}"); // close tab.
                    Thread.Sleep(100);
                }
                next++;
                SendKeys.SendWait("^{TAB}"); // change focus to next tab
                Thread.Sleep(100);
            }
            catch (Exception ex)
            {
                // Chrome internal process, doesn't have tab.

            }               
        }

        if (isMinimized)
        {
            ShowWindow(hWnd, 6); // minimize again
            Thread.Sleep(100);
        }

        hWnd = Process.GetCurrentProcess().MainWindowHandle;
        SetForegroundWindow(hWnd);
        Thread.Sleep(100);

        Console.WriteLine("Closed youtube tabs");

        Console.ReadKey();
    }

}

2
2018-01-27 18:17





仅使用YouTube杀死Chrome标签并不能解决实际问题。我认为迫使所有工作站进入睡眠状态会更容易,也更可靠。

来自的东西 这个帖子 应该做的伎俩。 rundll32.exe powrprof.dll,SetSuspendState 0,1,0 也许?


1
2018-02-02 20:27





使用AutoHotkey可以轻松完成

这是一个打开Chrome的脚本,循环显示所有标签并关闭YouTube,然后再次最小化Chrome

#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

SetTitleMatchMode, 2


IfWinExist, ahk_class Chrome_WidgetWin_1
{
    WinActivate, Chrome
    WinGetActiveTitle, ActiveWindowOld
    Loop {
        Send, ^{Tab}
        Sleep, 500
        WinGetActiveTitle, ActiveWindow
        if (ActiveWindow = ActiveWindowOld)
        {
            break
        }
        IfInString, ActiveWindow, YouTube - Google Chrome
        {
            Send, ^{w}
        }
    }
    WinMinimize, Chrome
}

信用: https://autohotkey.com/board/topic/148742-cycling-through-all-chrome-tabs-and-closing-a-specific-tab/


1
2018-02-03 09:41





if (SearchBar != null)
{
    bool valuePatternExist = (bool)SearchBar.GetCurrentPropertyValue(AutomationElement.IsValuePatternAvailableProperty);
    if (valuePatternExist)
    {
        ValuePattern val = SearchBar.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
        if (val.Current.Value.Contains("youtube.com") || val.Current.Value.Contains("youtube.co.uk"))
            proc.Close();
    }
}

1
2018-02-03 15:53