如何获取Windows / C#中顶级窗口的进程名称和标题

正如在主题…或更好 – 如何从顶部窗口更改时事件中获取此信息?

感谢提示。 所以我应该使用P / Invoke。 这里是完整的代码:

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; namespace CuckooCoach { class Monitor { [DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll")] static extern int GetWindowTextLength(IntPtr hWnd); // int GetWindowText( // __in HWND hWnd, // __out LPTSTR lpString, // __in int nMaxCount // ); [DllImport("user32.dll")] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); // DWORD GetWindowThreadProcessId( // __in HWND hWnd, // __out LPDWORD lpdwProcessId // ); [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); //HANDLE WINAPI OpenProcess( // __in DWORD dwDesiredAccess, // __in BOOL bInheritHandle, // __in DWORD dwProcessId //); [DllImport("kernel32.dll")] private static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId); [DllImport("kernel32.dll")] private static extern bool CloseHandle(IntPtr handle); // DWORD WINAPI GetmoduleeBaseName( // __in HANDLE hProcess, // __in_opt HMODULE hmodulee, // __out LPTSTR lpBaseName, // __in DWORD nSize // ); [DllImport("psapi.dll")] private static extern uint GetmoduleeBaseName(IntPtr hWnd, IntPtr hmodulee, StringBuilder lpFileName, int nSize); // DWORD WINAPI GetmoduleeFileNameEx( // __in HANDLE hProcess, // __in_opt HMODULE hmodulee, // __out LPTSTR lpFilename, // __in DWORD nSize // ); [DllImport("psapi.dll")] private static extern uint GetmoduleeFileNameEx(IntPtr hWnd, IntPtr hmodulee, StringBuilder lpFileName, int nSize); public static string GetTopWindowText() { IntPtr hWnd = GetForegroundWindow(); int length = GetWindowTextLength(hWnd); StringBuilder text = new StringBuilder(length + 1); GetWindowText(hWnd, text, text.Capacity); return text.ToString(); } public static string GetTopWindowName() { IntPtr hWnd = GetForegroundWindow(); uint lpdwProcessId; GetWindowThreadProcessId(hWnd, out lpdwProcessId); IntPtr hProcess = OpenProcess(0x0410, false, lpdwProcessId); StringBuilder text = new StringBuilder(1000); //GetmoduleeBaseName(hProcess, IntPtr.Zero, text, text.Capacity); GetmoduleeFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity); CloseHandle(hProcess); return text.ToString(); } } } 

您可以使用此代码按进程名称查找窗口句柄:

  Process[] processes = Process.GetProcessesByName(m.ProcessName); if (processes != null && processes.Length > 0) { Process process = processes[0]; process.StartInfo.WindowStyle = ProcessWindowStyle.Normal; process.Refresh(); if (process.MainWindowHandle != IntPtr.Zero) { // process.mainwindows handle is needed for you 

比你可以找到窗口文本的句柄title = GetWindowTitle(process.MainWindowHandle);

 private String GetWindowTitle(IntPtr hWn) { object LParam = new object(); int WParam = 0; StringBuilder title = new StringBuilder(1024); SendMessage(hWn, WM_GETTEXT, WParam, LParam); GetWindowText(hWn, title, title.Capacity); return title.ToString(); } 

您需要以下声明来调用winapi函数:

  [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount); [DllImport("User32.dll", EntryPoint = "SendMessage")] public static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, object lParam); 

我不认为有这样一个.Net的方式,所以我想你会使用PInvoke。

这是一些示例代码http://www.pinvoke.net/default.aspx/user32.getforegroundwindow

正如在该链接中可以看到的那样,如果你不想自己处理PInvoke代码,那么就有一个项目(Managed Windows API)将其包装在托管代码中。

对于窗口标题,你必须用从GetForegroundWindow()返回的HWND进行GetWindowText的P / Invoke。

至于进程信息,我相信P /调用GetWindowmoduleeFileName应该工作。