Using system. runtime. interopservices; <br/> [dllimport ("user32.dll")] <br/> Public static extern int sendmessage (intptr hwnd, uint MSG, int wparam, int lparam ); <br/> Public Delegate bool wndenumproc (intptr hwnd, int lparam); <br/> [dllimport ("user32.dll")] <br/> Public static extern int enumwindows (wndenumproc lpenumfunc, int lparam); <br/> [dllimport ("user32.dll")] <br/> Public static extern int enumchi Ldwindows (intptr hwndparent, <br/> wndenumproc lpenumfunc, int lparam); <br/> [dllimport ("user32.dll")] <br/> Public static extern int getwindowtext (intptr hwnd, stringbuilder lpstring, <br/> int nmaxcount); <br/> [dllimport ("user32.dll")] <br/> Public static extern int getclassname (intptr hwnd, stringbuilder lpclassname, <br/> int nmaxcount); <br/> [dllimport ("user32.dll")] <br/> Public static extern B OOl iswindow (intptr hwnd); <br/> [dllimport ("user32.dll")] <br/> Public static extern bool iswindowvisible (intptr hwnd ); <br/> [dllimport ("user32.dll")] <br/> Public static extern intptr find1_wex (intptr hwndparent, <br/> intptr hwndchildafter, string lpszclass, string lpszwindow ); <br/> [dllimport ("user32.dll")] <br/> Public static extern uint getwindowthreadprocessid (intptr hwnd, <br/> out uint DWP Rocessid); <br/> [dllimport ("psapi. DLL ")] <br/> Public static extern uint getmodulebasename (intptr hprocess, intptr hmodule, <br/> stringbuilder lpbasename, uint nsize ); <br/> Public const uint process_vm_operation = 0x0008; <br/> Public const uint process_vm_read = 0x0010; <br/> Public const uint process_vm_write = 0x0020; <br/> Public const uint process_query_information = 0x0400; <br/> [dllimport ("ker Nel32.dll ")] <br/> Public static extern intptr OpenProcess (uint dwdesiredaccess, <br/> bool binherithandle, uint dwprocessid); <br/> [dllimport (" kernel32.dll ")] <br/> Public static extern bool closehandle (intptr handle); <br/> [dllimport ("user32.dll")] <br/> Public static extern int getwindowlong (intptr hwnd, int nindex); <br/> Public const int gwl_style =-16; <br/> Public const int es_readonly = 0x800; <Br/> Public const uint mem_commit = 0x1000; <br/> Public const uint mem_release = 0x8000; <br/> Public const uint mem_reserve = 0x2000; <br/> Public const uint page_readwrite = 4; <br/> [dllimport ("kernel32.dll")] <br/> Public static extern intptr virtualallocex (intptr hprocess, intptr lpaddress, <br/> uint dwsize, uint flallocationtype, uint flprotect); <br/> [dllimport ("kernel32.dll")] <br/> Public St Atic extern bool virtualfreeex (intptr hprocess, intptr lpaddress, <br/> uint dwsize, uint dwfreetype); <br/> [dllimport ("kernel32.dll")] <br/> Public static extern bool writeprocessmemory (intptr hprocess, intptr lpbaseaddress, <br/> intptr lpbuffer, int nsize, ref uint vnumberofbytesread ); <br/> [dllimport ("kernel32.dll")] <br/> Public static extern bool readprocessmemory (intptr hprocess, intptr lpbas Eaddress, <br/> intptr lpbuffer, int nsize, ref uint vnumberofbytesread); <br/> private intptr richhandle; <br/> Public String getprocessname (uint aprocessid) <br/>{ <br/> stringbuilder vbuffer = new stringbuilder (256); <br/> intptr vprocess = OpenProcess (<br/> process_query_information | process_vm_read, false, aprocessid ); <br/> try <br/>{< br/> If (getmodulebasename (vprocess, intptr. zero, vbuff Er, <br/> (uint) vbuffer. capacity)> 0) <br/> return vbuffer. tostring (); <br/> else return string. empty; <br/>}< br/> finally <br/> {<br/> closehandle (vprocess ); <br/>}< br/> Public bool enumchild (intptr hwnd, int lparam) <br/>{< br/> If (! Iswindowvisible (hwnd) return true; // invisible <br/> stringbuilder vbuffer = new stringbuilder (256); <br/> getclassname (hwnd, vbuffer, vbuffer. capacity); <br/> If (vbuffer. tostring (). tolower () = "RICHEDIT20A") <br/>{< br/> If (getwindowlong (hwnd, gwl_style) & es_readonly )! = Es_readonly) // non-read-only <br/>{< br/> richhandle = hwnd; <br/> return false; <br/>}< br/> return true; <br/>}< br/> Public bool enumfunc (intptr hwnd, int lparam) <br/>{< br/> If (! Iswindowvisible (hwnd) return true; // invisible <br/> stringbuilder vbuffer = new stringbuilder (256); <br/> getclassname (hwnd, vbuffer, vbuffer. capacity); <br/> If (vbuffer. tostring () = "#32770") <br/>{< br/> uint vprocessid; <br/> getwindowthreadprocessid (hwnd, out vprocessid ); <br/> If (getprocessname (vprocessid ). tolower () = "qq.exe") <br/>{< br/> getwindowtext (hwnd, vbuffer, vbuffer. capacity); <br /> If (vbuffer. tostring (). indexof ("chatting")> = 0) // The title contains "chatting" <br/> {<br/> enumchildwindows (hwnd, @ enumchild, lparam ); <br/> return false; <br/>}< br/> return true; <br/>}< br/> [structlayout (layoutkind. sequential)] <br/> public struct gettextlengthex <br/>{< br/> Public uint flags; <br/> Public uint codePage; <br/>}< br/> [structlayout (layoutkind. sequential)] <br/> public struct gett Extex <br/>{< br/> Public int CB; <br/> Public int flags; <br/> Public int codePage; <br/> Public intptr lpdefaultchar; <br/> Public intptr lpuseddefchar; <br/>}; <br/> Public const int gtl_default = 0; <br/> Public const int gt_default = 0; <br/> Public const int wm_user = 0x0400; <br/> Public const int em_gettextex = wm_user + 94; <br/> Public const int em_gettextlengthex = wm_user + 95; <br/> Public String process_readrichedittext (intptr ahandle) <br/>{< br/> If (! Iswindow (ahandle) return string. empty; <br/> string vreturn = string. empty; <br/> uint vprocessid; <br/> getwindowthreadprocessid (ahandle, out vprocessid); <br/> intptr vprocess = OpenProcess (kernel | process_vm_read | <br/> process_vm_write, false, vprocessid); <br/> try <br/>{< br/> uint vnumberofbytesread = 0; <br/> intptr vpointer = virtualallocex (vprocess, intptr. zero, 0x1000, <br/> mem_reserve | mem_commit, page_readwrite); <br/> gettextlengthex vgettextlengthex = new gettextlengthex (); <br/> vgettextlengthex. flags = gtl_default; <br/> vgettextlengthex. codePage = 1200; // Unicode <br/> intptr vaddress = marshal. alloccotaskmem (marshal. sizeof (vgettextlengthex); <br/> marshal. structuretoptr (vgettextlengthex, vaddress, false); <br/> writeprocessmemory (vprocess, vpointer, vaddress, <br/> marshal. sizeof (vgettextlengthex), ref vnumberofbytesread); <br/> marshal. freecotaskmem (vaddress); <br/> int L = sendmessage (ahandle, em_gettextlengthex, (INT) vpointer, 0); <br/> virtualfreeex (vprocess, vpointer, 0, mem_release); <br/> If (L <= 0) return vreturn; <br/> gettextex vgettextex = new gettextex (); <br/> vgettextex. CB = L * 2 + 2; <br/> vgettextex. flags = gt_default; <br/> vgettextex. codePage = 1200; // Unicode <br/> vgettextex. lpdefaultchar = intptr. zero; <br/> vgettextex. lpuseddefchar = intptr. zero; <br/> vpointer = virtualallocex (vprocess, intptr. zero, <br/> (uint) (marshal. sizeof (vgettextex) + L * 2 + 2), <br/> mem_reserve | mem_commit, page_readwrite); <br/> vaddress = marshal. alloccotaskmem (marshal. sizeof (vgettextex); <br/> marshal. structuretoptr (vgettextex, vaddress, false); <br/> writeprocessmemory (vprocess, vpointer, vaddress, <br/> marshal. sizeof (vgettextex), ref vnumberofbytesread); <br/> marshal. freecotaskmem (vaddress); <br/> sendmessage (ahandle, em_gettextex, (INT) vpointer, <br/> (INT) vpointer + marshal. sizeof (vgettextex); <br/> vaddress = marshal. alloccotaskmem (L * 2); <br/> readprocessmemory (vprocess, <br/> (intptr) (INT) vpointer + marshal. sizeof (vgettextex), <br/> vaddress, L * 2, ref vnumberofbytesread); <br/> vreturn = marshal. ptrtostringuni (vaddress, L * 2); <br/> marshal. freecotaskmem (vaddress); <br/> virtualfreeex (vprocess, vpointer, 0, mem_release ); <br/>}< br/> finally <br/>{< br/> closehandle (vprocess); <br/>}< br/> return vreturn; <br/>}< br/> private void button#click (Object sender, eventargs e) <br/>{< br/> richhandle = intptr. zero; <br/> enumwindows (enumfunc, 0); <br/> If (richhandle = intptr. zero) return; <br/> console. writeline (process_readrichedittext (richhandle); <br/>}
Original article: http://blog.csdn.net/zswang/archive/2008/01/02/2009868.aspx