如何在 Windows / C# 上获取顶部窗口的进程名称和标题
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2635404/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get process name and title of the top window on Windows / C#
提问by Michal Czardybon
As in the topic... or better - how to get this information from events when the top window changes?
正如在主题中......或更好 - 当顶部窗口发生变化时如何从事件中获取此信息?
回答by Michal Czardybon
Thanks for hints. So I should use P/Invoke anyhow. Here is the complete code:
谢谢你的提示。所以无论如何我都应该使用 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 GetModuleBaseName(
// __in HANDLE hProcess,
// __in_opt HMODULE hModule,
// __out LPTSTR lpBaseName,
// __in DWORD nSize
// );
[DllImport("psapi.dll")]
private static extern uint GetModuleBaseName(IntPtr hWnd, IntPtr hModule, StringBuilder lpFileName, int nSize);
// DWORD WINAPI GetModuleFileNameEx(
// __in HANDLE hProcess,
// __in_opt HMODULE hModule,
// __out LPTSTR lpFilename,
// __in DWORD nSize
// );
[DllImport("psapi.dll")]
private static extern uint GetModuleFileNameEx(IntPtr hWnd, IntPtr hModule, 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);
//GetModuleBaseName(hProcess, IntPtr.Zero, text, text.Capacity);
GetModuleFileNameEx(hProcess, IntPtr.Zero, text, text.Capacity);
CloseHandle(hProcess);
return text.ToString();
}
}
}
回答by st78
You can find window handle by process name using this code:
您可以使用以下代码按进程名称查找窗口句柄:
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
and than you can find window text by handle title = GetWindowTitle(process.MainWindowHandle);
然后你可以通过句柄标题 = 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();
}
You need following declarations to call winapi functions:
您需要以下声明来调用 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);
回答by Hans Olsson
I don't think there is a .Net way of doing this, so I think you will have use PInvoke.
我不认为有这样做的 .Net 方式,所以我认为你会使用 PInvoke。
Here's some sample code http://www.pinvoke.net/default.aspx/user32.getforegroundwindow
这是一些示例代码http://www.pinvoke.net/default.aspx/user32.getforegroundwindow
And as can be seen in that link there's a project (Managed Windows API) that wraps that up in managed code if you don't want to deal with the PInvoke code yourself.
从该链接中可以看出,如果您不想自己处理 PInvoke 代码,则有一个项目(托管 Windows API)将其封装在托管代码中。
回答by anonymous
For the window title, you'll have to do a P/Invoke of GetWindowTextwith the HWND returned from GetForegroundWindow().
对于窗口标题,您必须使用从 GetForegroundWindow() 返回的 HWND 执行GetWindowText的 P/Invoke 。
As for the process info, I believe that P/Invoking GetWindowModuleFileNameshould work.
至于进程信息,我相信 P/Invoking GetWindowModuleFileName应该可以工作。