[Win] 通过processID得到WindowHandle

这个问题可能已经是老生常谈的问题了。 

就是怎么通过仅有的exe文件名,然后得到其processID进而得到Handle,然后给其发送消息。

可能有很多很多方法,我这个方法也不是最好的,但是还是要记录下,以后可以参考。

并抛出一个问题。Google了很多时间都没有找到确切的答案。

0. 我们的目标是得到窗口Handle。一个简单的方法就是根据 窗口名字 直接利用FindWindow得到WindowHandle。

上面这个方法看似简单,但是一个致命弱点就是,如果一个exe程序不是自己编写的,其实根本无法知道主窗口的title到底是什么。

所以此方法适用性不是很广。

 

下面就介绍从exe程序名得到主窗口Handle的方法。

1. 首先,从exe name得到processID。

这个应该有很多方法。我利用了一个cmd的命令方式得到。可能方法比较效率低,但是实现还是比较方便的。 

即使用 tasklist命令。 因为有很多参数和配置可以选择,所以可以比较简便得到exe name和processID之间的对应关系。

e.g.  tasklist /FI “IMAGENAME eq test.exe”/FO CSV /NH

/FI 就是一个匹配规则,具体可以参照help

/FO 就是选择输出格式,例子中为CSV

/NH 就是输出没有标题

输出的结果就是exe名字和processID对应关系。

 

2. 如何从processID得到窗口句柄

 1 HWND h = ::GetTopWindow(0 );
2 while ( h )
3 {
4 DWORD pid;
5 DWORD dwTheardId = ::GetWindowThreadProcessId( h,&pid);
6 if ( pid == /*your process id*/ )
7 {
8 // here h is the handle to the window
9 break;
10 }
11 h = ::GetNextWindow( h , GW_HWNDNEXT);
12 }

这个非常容易理解。循环寻找是不是和自己需要的processID相互匹配。 

如果匹配了就是需要的窗口句柄了。

但是此处抛出一个问题,就是一个processID可能对应了很多窗口Handle,到底哪个是exe程序的主窗口呢。

我想了一个迂回方法,可能只是一个trick,但是至少能基本解决现在的问题。 

 

3. GetWindowText 可以得到窗口title。这样对一些常规不相关的窗口过滤掉。 

还有就是检查所有processID对应的窗口,如果其属性是Visible的,这样就可以断定这些都是想让用户看到的主要窗口。

这样就可以对这些窗口依次发送需要的消息,进行后续的工作了。

 

最后,就是一个问题如何解决:

如何通过一个processID直接得到exe程序的主窗口。

google了很多solution好像有人说基本不可能,或者说主窗口一般都有很多个~

 



posted @ 2012-02-18 00:47  JimmyQi  阅读(2209)  评论(0编辑  收藏  举报