如何用C#程序获取Chrome内文本并实现快捷短语替换功能?
Hey there! Let's break down your two questions step by step—first building that text expansion feature with user32.dll, then grabbing text from Google Chrome in C#.
user32.dll in C# You’ve already mapped out the core steps, so let’s translate those into working code and fill in the gaps for actually replacing the shortcut phrase with your full text.
First, we’ll need to import the necessary user32.dll functions via P/Invoke. Here’s the setup:
using System; using System.Runtime.InteropServices; public class TextExpander { // Import required user32.dll functions [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); [DllImport("user32.dll")] private static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach); [DllImport("user32.dll")] private static extern IntPtr GetFocus(); [DllImport("user32.dll", CharSet = CharSet.Auto)] private static extern int SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, string lParam); [DllImport("user32.dll")] private static extern uint GetCurrentThreadId(); // Windows message constants private const uint WM_SETTEXT = 0x000C; private const uint WM_KEYDOWN = 0x0100; private const uint VK_BACK = 0x08; public static void ExpandShortcut(string shortcut, string fullText) { // Step 1: Get the active window handle IntPtr activeWindow = GetForegroundWindow(); if (activeWindow == IntPtr.Zero) return; // Step 2: Get the active window's thread ID GetWindowThreadProcessId(activeWindow, out uint activeThreadId); uint currentThreadId = GetCurrentThreadId(); try { // Step 3: Attach our thread to the active window's input thread // This lets us access the focused control in the target window if (!AttachThreadInput(currentThreadId, activeThreadId, true)) return; // Step 4: Get the handle of the focused control IntPtr focusedControl = GetFocus(); if (focusedControl == IntPtr.Zero) return; // Optional: First delete the shortcut text (assuming it's the last thing typed) // Send BACKSPACE keys equal to the length of the shortcut for (int i = 0; i < shortcut.Length; i++) { SendMessage(focusedControl, WM_KEYDOWN, (IntPtr)VK_BACK, IntPtr.Zero); } // Step 5: Send the full text to the focused control SendMessage(focusedControl, WM_SETTEXT, IntPtr.Zero, fullText); } finally { // Always detach our thread to avoid leaks AttachThreadInput(currentThreadId, activeThreadId, false); } } }
How to use this:
- Call
TextExpander.ExpandShortcut("BNN", "Hi I am Banana")when your shortcut key is pressed (you’ll need to add global hotkey handling separately, which can also useuser32.dllfunctions likeRegisterHotKey). - The code first deletes the shortcut text (using BACKSPACE presses) then inserts the full phrase. Adjust this logic if you need to handle selected text or different input scenarios.
There are two solid approaches here, depending on whether you want text from Chrome’s UI (like the address bar) or the web page content itself.
Option 1: Windows UI Automation (for Chrome UI elements)
This lets you interact with Chrome’s native controls (address bar, input fields, etc.) using the Windows Automation API.
First, add references to UIAutomationClient and UIAutomationTypes in your project. Then use this code:
using System; using System.Windows.Automation; public class ChromeTextGrabber { public static string GetChromeAddressBarText() { // Find the Chrome window by class name AutomationElement chromeWindow = AutomationElement.RootElement.FindFirst( TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "Chrome_WidgetWin_1") ); if (chromeWindow == null) return "Chrome window not found"; // Find the address bar element AutomationElement addressBar = chromeWindow.FindFirst( TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit) ); return addressBar?.GetCurrentPropertyValue(ValuePattern.ValueProperty) as string ?? "Address bar not found"; } // You can extend this to find other elements (like page input fields) by adjusting the property conditions }
Option 2: Chrome DevTools Protocol (for web page content)
This is the most reliable way to get text directly from the web page itself. It uses Chrome’s built-in debugging protocol to run JavaScript and fetch content.
First, install the ChromeDevTools NuGet package. Then:
- Launch Chrome with the remote debugging port enabled:
chrome.exe --remote-debugging-port=9222 - Use this code to connect and fetch page text:
using System; using System.Threading.Tasks; using ChromeDevTools; using ChromeDevTools.Runtime; public class ChromePageTextGrabber { public static async Task<string> GetPageTextAsync() { // Connect to Chrome's debugging port var client = await ChromeClient.ConnectAsync("localhost", 9222); // Evaluate JavaScript to get the page's full text content var result = await client.Runtime.EvaluateAsync("document.body.innerText"); return result.Result.Value.ToString(); } }
Notes:
- For the DevTools approach, make sure Chrome is running with the debug port open. You can also automate launching Chrome with this flag from your C# code if needed.
- This method works for any web page content—you can modify the JavaScript snippet to target specific elements (e.g.,
document.getElementById('my-input').valuefor an input field).
内容的提问来源于stack exchange,提问作者Banana

