在做一个监控项目,简单点来说就是A.exe是一个主程序,但有时不知道它会在怎样的一个状态,所以有一个B.exe来对其进行实时监控,获得各项运行状态。试了几种进程通信的方法,觉得有一种真是简单又实用,就是利用FindWindow和SendMessage,特此记下。
首先说FindWindow。
FindWindow返回与指定字符创相匹配的窗口类名或窗口名的最顶层窗口的窗口句柄。函数原型为:
C++:
HWND FindWindow(LPCTSTR lpClassName,LPCTSTR lpWindowName );
C#:
[DllImport("User32.dll", EntryPoint = "FindWindow")]
int FindWindow(string lpClassName, string lpWindowName);
lpClassName就是窗口类名,大多数情况不会用到它。lpWindowName是窗口名,就是窗口标题,任何一个窗口都有标题,当然也会有相同标题的,那只会找到在z-order最上层的窗口。
再看SendMessage,稍微复杂一点,它是通信的主力军。
SendMessage将指定的消息发送到一个或多个窗口。函数原型为:
C++:
LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
C#:
[DllImport("User32.dll", EntryPoint = "SendMessage")]
int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
hWnd是接收消息的窗口的句柄。Msg是将被发送的消息。wParam和IParam都是指定附加的消息信息。
这里仅仅介绍怎样利用它们实现进程通信,其实都还有很多功能,不再详述。
要用SendMessage需要知道窗口句柄,这个当然是通过FindWindow,还需要知道是什么消息,在这里用的是0x004A,一般变量命名为WM_COPYDATA,还有就是所要发送的消息信息了,就是具体内容,就需要一个特定的结构COPYDATASTRUCT,原型为:
C++:
struct COPYDATASTRUCT {ULONG_PTR dwData;DWORD cbData;PVOID lpData;}
C#:
struct COPYDATASTRUCT{IntPtr dwData;public int cbData;[MarshalAs(UnmanagedType.LPStr)]public string lpData;}
好了这样就可以发送消息到另一个窗口上,代码如下:
C++:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
C#:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
发送完了,那接收窗口就要接收了,怎样接收呢,也很简单还是根据消息0x004A来获得。代码如下:
C++:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
C#:
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
很简单吧,代码不多,应该很容易看懂。