C#获取进程的主窗口句柄的实现方法
通过调用win32 api实现。
public class user32api
{
private static hashtable processwnd = null;
public delegate bool wndenumproc(intptr hwnd, uint lparam);
static user32api()
{
if (processwnd == null)
{
processwnd = new hashtable();
}
}
[dllimport("user32.dll", entrypoint = "enumwindows", setlasterror = true)]
public static extern bool enumwindows(wndenumproc lpenumfunc, uint lparam);
[dllimport("user32.dll", entrypoint = "getparent", setlasterror = true)]
public static extern intptr getparent(intptr hwnd);
[dllimport("user32.dll", entrypoint = "getwindowthreadprocessid")]
public static extern uint getwindowthreadprocessid(intptr hwnd, ref uint lpdwprocessid);
[dllimport("user32.dll", entrypoint = "iswindow")]
public static extern bool iswindow(intptr hwnd);
[dllimport("kernel32.dll", entrypoint = "setlasterror")]
public static extern void setlasterror(uint dwerrcode);
public static intptr getcurrentwindowhandle()
{
intptr ptrwnd = intptr.zero;
uint uipid = (uint)process.getcurrentprocess().id; // 当前进程 id
object objwnd = processwnd[uipid];
if (objwnd != null)
{
ptrwnd = (intptr)objwnd;
if (ptrwnd != intptr.zero && iswindow(ptrwnd)) // 从缓存中获取句柄
{
return ptrwnd;
}
else
{
ptrwnd = intptr.zero;
}
}
bool bresult = enumwindows(new wndenumproc(enumwindowsproc), uipid);
// 枚举窗口返回 false 并且没有错误号时表明获取成功
if (!bresult && marshal.getlastwin32error() == 0)
{
objwnd = processwnd[uipid];
if (objwnd != null)
{
ptrwnd = (intptr)objwnd;
}
}
return ptrwnd;
}
private static bool enumwindowsproc(intptr hwnd, uint lparam)
{
uint uipid = 0;
if (getparent(hwnd) == intptr.zero)
{
getwindowthreadprocessid(hwnd, ref uipid);
if (uipid == lparam) // 找到进程对应的主窗口句柄
{
processwnd[uipid] = hwnd; // 把句柄缓存起来
setlasterror(0); // 设置无错误
return false; // 返回 false 以终止枚举窗口
}
}
return true;
}
}
调用user32api.getcurrentwindowhandle()即可返回当前进程的主窗口句柄,如果获取失败则返回intptr.zero。
--eof--