失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > C#-遍历进程获取主窗口句柄

C#-遍历进程获取主窗口句柄

时间:2019-04-12 18:51:50

相关推荐

C#-遍历进程获取主窗口句柄

C#遍历进程获取主窗口句柄

wyq1153

C#遍历进程获取主窗口句柄

当我们启动一个程序,用 Process process = Process.Start(path);//path是程序的绝对路径

启动时,获取的process.Handle其实是进程的句柄,并不是窗口的句柄,而有时process.MainWindowHandle却等于0

此时就需要用枚举来获取启动进程的主窗口句柄了,代码如下:

/// <summary>

/// 用于枚举子窗体是的委托

/// </summary>

/// <param name="WindowHandle">窗体句柄</param>

/// <param name="num">自定义</param>

/// <returns></returns>

public delegate bool EnumChildWindow(IntPtr WindowHandle, string num);

/// <summary>

/// 获取指定窗体的所有子窗体

/// </summary>

/// <param name="WinHandle">窗体句柄</param>

/// <param name="ec">回调委托</param>

/// <param name="name">自定义</param>

/// <returns></returns>

[DllImport("User32.dll")]

public static extern int EnumChildWindows(IntPtr WinHandle, EnumChildWindow ecw, string name);

/// <summary>

/// 获取指定窗体的标题

/// </summary>

/// <param name="WinHandle">窗体句柄</param>

/// <param name="Title">缓冲区取用于存储标题</param>

/// <param name="size">缓冲区大小</param>

/// <returns></returns>

[DllImport("User32.dll")]

public static extern int GetWindowText(IntPtr WinHandle, StringBuilder Title, int size);

/// <summary>

/// 获取窗体类型

/// </summary>

/// <param name="WinHandle">窗体句柄</param>

/// <param name="Type">类型</param>

/// <param name="size">缓冲区大小</param>

/// <returns></returns>

[DllImport("user32.dll")]

public static extern int GetClassName(IntPtr WinHandle, StringBuilder Type, int size);

/// <summary>

/// 根据句柄获得进程id值

/// </summary>

/// <param name="handle">句柄</param>

/// <param name="pid"></param>

/// <returns></returns>

[DllImport("user32")]

private static extern int GetWindowThreadProcessId(IntPtr handle, out int pid);

IntPtr mainHwnd = IntPtr.Zero;//登录窗口句柄

string typeName = string.Empty;//启动程序的窗口标题

/// <summary>

/// 枚举窗体

/// </summary>

/// <param name="handle"></param>

/// <param name="num"></param>

/// <returns></returns>

private bool EnumChild(IntPtr handle, string num)

{

StringBuilder title = new StringBuilder();

//StringBuilder type = new StringBuilder();

title.Length = 100;

//type.Length = 100;

GetWindowText(handle, title, 100);//取标题

//GetClassName(handle, type, 100);//取类型

if (title.ToString() == typeName)

{

mainHwnd = handle;

return false;

}

return true;

}

//代码调用

pubilc boolTest()

{

FileVersionInfo myFileVersion = FileVersionInfo.GetVersionInfo(path);

typeName = myFileVersion.ProductName;//获取程序产品名称

int waitTime = 0;

while (true)

{

EnumChildWindow ecw = new EnumChildWindow(EnumChild);

EnumChildWindows(mainWindowHandle, ecw, "");

GetWindowRect(mainHwnd.ToInt32(), ref rectMain);

int pid = 0;

GetWindowThreadProcessId(mainHwnd, out pid);

//rectMain.Height - rectMain.Y < 300说明是登录窗口

if (mainHwnd != IntPtr.Zero && process.Id == pid && rectMain.Height - rectMain.Y < 300)//276

break;

waitTime++;

//30秒没打开程序,登录失败

if (waitTime >= 30)

return false;

Thread.Sleep(1000);

}

return true;

}

=========================================================================

另外一个参考:

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。

转自/slyzly/articles/2331487.html

如果觉得《C#-遍历进程获取主窗口句柄》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。