本文介绍了如何在其他应用程序中设置窗口挂钩?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 事实上,我是一个绿色的手,我试图理解一些像HOOK.Uh这样的技术....不幸的是我失败了,也许我失败了,请帮助我,我试着设置一个窗口挂钩一些应用程序,例如IE, 使用系统; 使用 System.Collections.Generic; 使用 System.ComponentModel; 使用 System.Data; 使用 System.Drawing; 使用 System.Linq; 使用 System.Text; 使用 System.Windows.Forms; 使用 System.Runtime.InteropServices; 使用 System.Diagnostics; 命名空间笔记本hook { public partial class Form1:Form { [DllImport( ,字符集= CharSet.Auto,CallingConvention = CallingConvention.StdCall)] 私人静态外部的IntPtr的GetModuleHandle(串lpModuleName) ; [DllImport( kernel32,CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall )] 私人 静态 extern int GetCurrentThreadId(); [DllImport( User32.dll,CharSet = System.Runtime.InteropServices.CharSet .Auto)] 私人 静态 extern int GetWindowThreadProcessId( IntPtr hwnd, out int ID); [DllImport( User32.dll,CharSet = System.Runtime.InteropServices.CharSet .Auto)] public static extern bool SetForegroundWindow( IntPtr hWnd); [DllImport( kernel32,CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall )] public static extern IntPtr OpenProcess( uint fdwAccess, bool fInherit, uint IDProcess); [DllImport( kernel32,CharSet = CharSet.Auto,CallingConvention = CallingConvention.StdCall )] public static extern VirtualAllocEx来( hProcess,; const int WH_KEYBOARD = 13 ; const int PROCESS_ALL_ACCESS = 0x1F0FFF; // const int PROCESS_VM_READ = 0x0010; // const int PROCESS_VM_WRITE = 0x0020; [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode; public int scanCode; public int 标志; public int time; public int dwExtraInfo; } public void HOOK_Start() { if (hHook == 0 ) { IntPtr hWnd = NativeMethods.FindWindow( null , Internet Explorer); NativeMethods.HookProc hp = new NativeMethods.HookProc(KbHookProc); int outId; int pId; HHOOK = NativeMethods.SetWindowsHookEx(,马力, .Zero, GetWindowThreadProcessId(hWnd, out outId)); if (hHook == 0 ) { MessageBox.Show( dead start); toolStripStatusLabel1.Text = dead start; return ; } else toolStripStatusLabel1.Text = 成功!; } } 私有 void button1_Click( object sender,EventArgs e) { HOOK_Start(); } void 取消挂钩() { 如果(hHook > 0 ) { bool ret = NativeMethods.UnhookWindowsHookEx(hHook); if (ret == false ) { MessageBox.Show( 失败!); return ; } hHook = 0 ; toolStripStatusLabel1.Text = failed; } } public static int KbHookProc( int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0 ) { return NativeMethods。 CallNextHookEx(hHook,nCode,wParam,lParam); } else { int r = NativeMethods.CallNextHookEx(hHook,nCode,wParam,lParam); if (wParam ==( IntPtr ) 256 ) {} else { KeyboardHookStruct MyKeyboardHookStruct =(KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof (KeyboardHookStruct)); MessageBox.Show(MyKeyboardHookStruct.vkCode.ToString()); } return r; } } 私有 void Form1_FormClosing( object sender,FormClosingEventArgs e) { UnHook(); } 内部 静态 class NativeMethods { public delegate int HookProc( int nCode, IntPtr wParam, IntPtr lParam); [DllImport( user32.dll,EntryPoint = FindWindow,SetLastError = true ,CharSet = CharSet .Unicode)] 内部 静态 extern IntPtr FindWindow( string lpClassName, string lpWindowName); [DllImport( user32.dll,CharSet = CharSet.Auto,CallingConvention = CallingConvention .StdCall)] public static extern 调用SetWindowsHookEx( idHook,HOOKPROC lpfn, IntPtr hInstance, int threadId); [DllImport( user32.dll,CharSet = CharSet.Auto ,CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx( int idHook); [DllImport( user32.dll,CharSet = CharSet.Auto ,CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx( int idHook, int nCode, IntPtr wParam, IntPtr lParam); } private void button2_Click( object sender,EventArgs e) { UnHook(); } } } 它没有用.SetWindowsHookEx失败了。我的天啊! 也许有点乱。但是感谢你阅读上面的内容,我已经在很多网站上搜索了3周的解决方案。请解决它,或者显示你最好的代码!谢谢!解决方案 您可以创建全局钩子,也可以挂钩某个线程。通常,您在自己的进程中创建一个钩子(与安装钩子的钩子相同)或系统全局。如果你发现它的线程ID,一些外部进程怎么样?不确定,但你可以试试。通常,这不是钩子的使用方式。 查看 SetWindowsHookEx 的描述: http://msdn.microsoft。 com / zh-CN / library / windows / desktop / ms644990%28v = vs.85%29.aspx [ ^ ]。 阅读并注意 dwThreadId 参数和单词global。当此参数为零时,挂钩对于在同一桌面中运行的线程是全局的,这称为全局。您正在设置调用进程的线程ID,因此您的挂钩只能是您的调用进程的本地。您无法挂接任何其他进程,IE或不。 请参阅其余文档:某些挂钩仅适用于全局。 现在,根据微软的说法,如果你想安装一个全局钩子,你需要设置它并只在一个单独的钩子函数中提供原生DLL ;所以P / Invoke不适用于此。我总是尝试按照这个规则挂钩:只在一个单独的DLL中设置一个全局钩子,在任何地方设置一个本地钩子。我没有尝试挂钩单个外部进程的选定线程(Microsoft文档从未确定此类情况),但是,如果甚至可能(为什么不呢?)我担心它可能需要相同的规则:a单独的原生DLL。 另请参阅此CodeProject文章: .NET中的全局系统挂钩 [ ^ ]。 -SA The fact that I'm a green hand,and I try to understand some of the technical like HOOK.Uh....Unfortunately I failed,maybe I fail,Please help me,I try to set a window hook in some application ,such as IE,using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using System.Drawing;using System.Linq;using System.Text;using System.Windows.Forms;using System.Runtime.InteropServices;using System.Diagnostics;namespace 笔记本hook{ public partial class Form1 : Form { [DllImport("kernel32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]     private static extern IntPtr GetModuleHandle(string lpModuleName); [DllImport("kernel32", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] private static extern int GetCurrentThreadId (); [DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] private static extern int GetWindowThreadProcessId(IntPtr hwnd, out int ID); [DllImport("User32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)] public static extern bool SetForegroundWindow(IntPtr hWnd); [DllImport("kernel32", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr OpenProcess(uint fdwAccess,bool fInherit,uint IDProcess); [DllImport("kernel32", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern IntPtr VirtualAllocEx(IntPtr hProcess,int lpAddress,int dwSize,int flAllocationType,int flProtect); public Form1() { InitializeComponent(); } static int hHook = 0; const int WH_KEYBOARD = 13; const int PROCESS_ALL_ACCESS = 0x1F0FFF; // const int PROCESS_VM_READ = 0x0010; // const int PROCESS_VM_WRITE = 0x0020; [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } public void HOOK_Start() { if (hHook == 0) { IntPtr hWnd = NativeMethods.FindWindow(null, "Internet Explorer"); NativeMethods.HookProc hp = new NativeMethods.HookProc(KbHookProc); int outId; int pId; hHook = NativeMethods.SetWindowsHookEx(2, hp, IntPtr.Zero, GetWindowThreadProcessId(hWnd, out outId)); if (hHook == 0) { MessageBox.Show("dead start"); toolStripStatusLabel1.Text = "dead start"; return; } else toolStripStatusLabel1.Text = "success!"; } } private void button1_Click(object sender, EventArgs e) { HOOK_Start(); } void UnHook() { if (hHook > 0) { bool ret = NativeMethods.UnhookWindowsHookEx(hHook); if (ret == false) { MessageBox.Show("failed!"); return; } hHook = 0; toolStripStatusLabel1.Text="failed"; } } public static int KbHookProc(int nCode, IntPtr wParam, IntPtr lParam) { if (nCode < 0) { return NativeMethods.CallNextHookEx(hHook, nCode, wParam, lParam); } else { int r = NativeMethods.CallNextHookEx(hHook, nCode, wParam, lParam); if (wParam == (IntPtr)256) { } else { KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct)); MessageBox.Show(MyKeyboardHookStruct.vkCode.ToString()); }return r; } }private void Form1_FormClosing(object sender, FormClosingEventArgs e) { UnHook(); }internal static class NativeMethods { public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true, CharSet = CharSet.Unicode)] internal static extern IntPtr FindWindow(string lpClassName, string lpWindowName);[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern bool UnhookWindowsHookEx(int idHook); [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam); }private void button2_Click(object sender, EventArgs e){ UnHook();} }}it dosen't works.SetWindowsHookEx was failed.Oh my God!Maybe a bit messy.However thank you for reading the above,I have been searching for the resolvent in many website 3 weeks.Please solve it,or show your best code!Thanks! 解决方案 You can either create a global hook, or hook one certain thread. Usually, you make a hook in your own process (the same as the one installing the hook) or system-global. How about some external process, if you find out its thread ID? Not sure, but you can try. Normally, this is not how hooks are used.Look at the description of SetWindowsHookEx:http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx[^].Read it and pay attention for dwThreadId parameter and the word "global". When this parameter is zero, the hook is global to the threads running in the same desktop, which is referred as "global". You are setting the thread ID of the calling process, so your hook can only be local to your calling process. You cannot hook up any other process, IE or not.See the rest of documentation: some hooks are only applied to global only.Now, according to the Microsoft, if you want to install a global hook, you would need to set it and provide a hook function only in a separate native DLL; so P/Invoke won't work for this. I always tried hooking following this rule: set a global hook only in a separate DLL, and a local hook anywhere. I did not try to hook a selected thread of a single external process (Microsoft documentation is never certain about such cases), but, it if is even possible (why not though?) I'm afraid it may require the same rule: a separate native DLL.[EDIT]See also this CodeProject article: Global System Hooks in .NET[^].—SA 这篇关于如何在其他应用程序中设置窗口挂钩?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云!
08-20 08:42