使用c#获取Chrome浏览器标题

假设我打开了多个镀铬窗口(不是标签),
如何查看浏览器标题?

我尝试了以下方法:

Process[] p = Process.GetProcessesByName("chrome"); foreach (Process item in p) { Console.WriteLine(item.MainWindowTitle); } 

但它只返回我最后一个打开的窗口名称,所有其他都是空白..

我不得不做这样的事情,但涉及调用Windows API函数非常繁琐。 问题是Chrome似乎使用单个进程来处理多个窗口或其他一些奇怪的问题,这意味着简单的方法对我来说不起作用。

无论如何,尝试这个,看看它是否有效。 基本上,它使用Chrome窗口类名称(可能是Chrome_WidgetWin_0Chrome_WidgetWin_1 )来枚举具有该类名称的所有窗口,并返回非空白窗口的窗口标题。

请注意,由于某种原因,这也始终会返回名为"Chrome App Launcher"的Windows标题,因此您可能需要对其进行过滤。

注意:您也可以使用“MozillaWindowClass”为Firefox执行此操作,使用“IEFrame”对IE执行此操作(尽管其中任何一个都可能随着不同版本而更改)。

 using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Security; using System.Text; namespace Demo { class WindowsByClassFinder { public delegate bool EnumWindowsDelegate(IntPtr hWnd, IntPtr lparam); [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage"), SuppressUnmanagedCodeSecurity] [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage"), SuppressUnmanagedCodeSecurity] [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] public extern static bool EnumWindows(EnumWindowsDelegate lpEnumFunc, IntPtr lparam); [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage"), SuppressUnmanagedCodeSecurity] [DllImport("User32", CharSet=CharSet.Auto, SetLastError=true)] public static extern int GetWindowText(IntPtr windowHandle, StringBuilder stringBuilder, int nMaxCount); [DllImport("user32.dll", EntryPoint = "GetWindowTextLength", SetLastError = true)] internal static extern int GetWindowTextLength(IntPtr hwnd); /// Find the windows matching the specified class name. public static IEnumerable WindowsMatching(string className) { return new WindowsByClassFinder(className)._result; } private WindowsByClassFinder(string className) { _className = className; EnumWindows(callback, IntPtr.Zero); } private bool callback(IntPtr hWnd, IntPtr lparam) { if (GetClassName(hWnd, _apiResult, _apiResult.Capacity) != 0) { if (string.CompareOrdinal(_apiResult.ToString(), _className) == 0) { _result.Add(hWnd); } } return true; // Keep enumerating. } public static IEnumerable WindowTitlesForClass(string className) { foreach (var windowHandle in WindowsMatchingClassName(className)) { int length = GetWindowTextLength(windowHandle); StringBuilder sb = new StringBuilder(length + 1); GetWindowText(windowHandle, sb, sb.Capacity); yield return sb.ToString(); } } public static IEnumerable WindowsMatchingClassName(string className) { if (string.IsNullOrWhiteSpace(className)) throw new ArgumentOutOfRangeException("className", className, "className can't be null or blank."); return WindowsMatching(className); } private readonly string _className; private readonly List _result = new List(); private readonly StringBuilder _apiResult = new StringBuilder(1024); } class Program { void run() { ChromeWindowTitles().Print(); } public IEnumerable ChromeWindowTitles() { foreach (var title in WindowsByClassFinder.WindowTitlesForClass("Chrome_WidgetWin_0")) if (!string.IsNullOrWhiteSpace(title)) yield return title; foreach (var title in WindowsByClassFinder.WindowTitlesForClass("Chrome_WidgetWin_1")) if (!string.IsNullOrWhiteSpace(title)) yield return title; } static void Main() { new Program().run(); } } static class DemoUtil { public static void Print(this object self) { Console.WriteLine(self); } public static void Print(this string self) { Console.WriteLine(self); } public static void Print(this IEnumerable self) { foreach (var item in self) Console.WriteLine(item); } } } 

我知道这已经得到了解答,但我也提出了一个解决方案,它在一个线程中枚举了所有Windows。

它是由Matthew Watson的解决方案构建的,因此有一些相似之处。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Diagnostics; using System.Runtime.InteropServices; namespace Chrome_Windows { class Program { [DllImport("user32.dll")] private static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); [DllImport("User32", CharSet = CharSet.Auto, SetLastError = true)] public static extern int GetWindowText(IntPtr windowHandle, StringBuilder stringBuilder, int nMaxCount); [DllImport("user32.dll", EntryPoint = "GetWindowTextLength", SetLastError = true)] internal static extern int GetWindowTextLength(IntPtr hwnd); private static List windowList; private static string _className; private static StringBuilder apiResult = new StringBuilder(256); //256 Is max class name length. private delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam); static void Main(string[] args) { List ChromeWindows = WindowsFinder("Chrome_WidgetWin_1", "chrome"); foreach (IntPtr windowHandle in ChromeWindows) { int length = GetWindowTextLength(windowHandle); StringBuilder sb = new StringBuilder(length + 1); GetWindowText(windowHandle, sb, sb.Capacity); Console.WriteLine(sb.ToString()); } } private static List WindowsFinder(string className, string process) { _className = className; windowList = new List(); Process[] chromeList = Process.GetProcessesByName(process); if (chromeList.Length > 0) { foreach (Process chrome in chromeList) { if (chrome.MainWindowHandle != IntPtr.Zero) { foreach (ProcessThread thread in chrome.Threads) { EnumThreadWindows((uint)thread.Id, new EnumThreadDelegate(EnumThreadCallback), IntPtr.Zero); } } } } return windowList; } static bool EnumThreadCallback(IntPtr hWnd, IntPtr lParam) { if (GetClassName(hWnd, apiResult, apiResult.Capacity) != 0) { if (string.CompareOrdinal(apiResult.ToString(), _className) == 0) { windowList.Add(hWnd); } } return true; } } } 

您必须获得进程列表。

遍历列表,只在名称为“chrome”的位置。

这将允许您获得所有标题。

因为如果您有多个镀铬工艺,那么您的电话只会给您一个,因为您只需拨打一次。

它返回的可能是另一个问题。 在你的情况下,它是最后一个。