Click here to Skip to main content
15,910,981 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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,
C#
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!
Posted
Comments
Sergey Alexandrovich Kryukov 1-Aug-13 12:25pm    
Just a note: even from my short answer (please see) you can see that the problem is quite delicate. Handling hooking problem in case of a global hook takes the most of experience and patience (notably, debugging can be difficult), so the problem might be a bit too difficult for a green hand. :-)
—SA

1 solution

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
 
Share this answer
 
v3
Comments
DragonetLi 4-Aug-13 10:58am    
I'm sorry to re-post,but don't want to do that,I try to do what you say,but it still fail,I need code,I need examples.
Sergey Alexandrovich Kryukov 4-Aug-13 22:49pm    
See also the article I referenced in my updated answer, after [EDIT].
—SA

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900