现在的位置: 首页 > 综合 > 正文

C# 全局钩子 方法二

2017年11月05日 ⁄ 综合 ⁄ 共 12658字 ⁄ 字号 评论关闭

//网上都说,我的朋友也说C#不能实现全局钩子获得listView之类的消息,只能实现全局的键盘和鼠标钩子,下面代码是在做得到其它程序的listView控件中的列表写的,不过没实现,项目只做了一半放下了,改其它方法实现了,本代码只供参考学习,如果哪位高手朋友做出来了,请把代码发一下,本人会非常感谢,再感谢的!!

using System;
using System.Collections.Generic;

using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
 

namespace AnShieldClassLibrary
{
   
        //public struct tagCWPSTRUCT
        //{
        //    public  IntPtr lParam;// 消息参数 
        //    public  IntPtr wParam;// 消息参数 
        //    public  int message;// 消息值,由非负整数来表示
        //    public  IntPtr hwnd;// 消息的目的地句柄
        //}
    

       [StructLayout(LayoutKind.Sequential)]
       public struct tagCWPSTRUCT
       {
           public IntPtr lParam;// 消息参数 
           public IntPtr wParam;// 消息参数 
           public int message;// 消息值,由非负整数来表示
           public IntPtr hwnd;// 消息的目的地句柄

           //public IntPtr lparam;
           //public IntPtr wparam;
           //public int message;
           //public IntPtr hwnd;
           //以前的
           //public int message;
           //public int paramL;
           //public int paramH;
           //public int Time;
           //public int hwnd;
       }
       //消息结构体
       [StructLayout(LayoutKind.Sequential)]
       public struct LVITEM
       {
           public int mask;
           public int iItem;
           public int iSubItem;
           public int state;
           public int stateMask;
           public string pszText; // string
           public int cchTextMax;
           public int iImage;
           public IntPtr lParam;
           public int iIndent;
           public int iGroupId;
           public int cColumns;
           public IntPtr puColumns;
       }
       //不用钩子得到窗口消息
       [StructLayout(LayoutKind.Sequential)]
       public struct CwpStruct
       {
           public IntPtr lparam;
           public IntPtr wparam;
           public int message;
           public IntPtr hwnd;
       }
       [StructLayout(LayoutKind.Sequential)]
       public struct DebugStruct
       {
           IntPtr idThread;
           IntPtr idThreadInstaller;
           IntPtr lParam;
           IntPtr wParam;
           int code;
       }
      [StructLayout(LayoutKind.Sequential)]
       public struct EventMsg
       {
           public int message;
           public int paramL;
           public int paramH;
           public int Time;
           public IntPtr hwnd;
       }

   public  class WanGuaClass
    {

        static int Lvm_First = 0x0000f;
        static int warningHook = 0;//句柄
        string strBarCode = "";

        public const int OPEN_PROCESS_ALL = 2035711;
        public const int PAGE_READWRITE = 4;
        public const int PROCESS_CREATE_THREAD = 2;
        public const int PROCESS_HEAP_ENTRY_BUSY = 4;
        public const int PROCESS_VM_OPERATION = 8;
        public const int PROCESS_VM_READ = 256;
        public const int PROCESS_VM_WRITE = 32;

        private const int PAGE_EXECUTE_READWRITE = 0x4;
        private const int MEM_COMMIT = 4096;
        private const int MEM_RELEASE = 0x8000;
        private const int MEM_DECOMMIT = 0x4000;
        private const int PROCESS_ALL_ACCESS = 0x1F0FFF;

        //查找窗体
         [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
        public extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("User32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);

        //将指定的消息发送到一个或多个窗口
        [DllImport("user32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
        [DllImport("user32.dll",EntryPoint="SendMessage")]
        public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);

        //发送后等待处理完才返回
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        public static extern int SendMessage(IntPtr wnd, int msg, IntPtr wP, IntPtr lP);
        [DllImport("User32.dll", EntryPoint = "PostMessage")]
        public static extern int PostMessage(IntPtr wnd, int msg, IntPtr wP, IntPtr lP);//发送完不管结果就返回
        [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")]//激活窗口
        public static extern int SetForegroundWindow(IntPtr hwnd);

        //得到目标进程句柄的函数
        [DllImport("User32.DLL")]
        public extern static int GetWindowThreadProcessId(int hwnd, ref IntPtr lpdwProcessId);
        [DllImport("User32.DLL")]
        public extern static int GetWindowThreadProcessId(IntPtr hwnd, ref IntPtr lpdwProcessId);

        //打开进程
        [DllImport("kernel32.dll")]
        public extern static int OpenProcess(int dwDesiredAccess,int bInheritHandle,int dwProcessId);
        [DllImport("kernel32.dll")]
        public extern static IntPtr OpenProcess( uint dwDesiredAccess,int bInheritHandle, uint dwProcessId);

        //关闭句柄的函数
        [DllImport("kernel32.dll", EntryPoint = "CloseHandle")]
        public static extern int CloseHandle(int hObject);
      
        //获取消息
        [DllImport("user32", EntryPoint = "GetMessage")]
        public static extern int GetMessage(out CwpStruct lpMsg, IntPtr hwnd, int wMsgFilterMin, int wMsgFilterMax);
     
        //读内存
        [DllImport("Kernel32.dll ")]
        public static extern Int32 ReadProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,[In, Out] byte[] buffer, int size,out IntPtr lpNumberOfBytesWritten);
        [DllImport("Kernel32.dll ")]
        public static extern Int32 ReadProcessMemory( int hProcess, int lpBaseAddress,ref int buffer,int size,int lpNumberOfBytesWritten);
        [DllImport("Kernel32.dll ")]
        public static extern Int32 ReadProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer, int size, int lpNumberOfBytesWritten );

        //写内存
        [DllImport("kernel32.dll")]
        public static extern Int32 WriteProcessMemory(IntPtr hProcess,IntPtr lpBaseAddress,[In, Out] byte[] buffer, int size, out IntPtr lpNumberOfBytesWritten );

        [DllImport("kernel32.dll")]
        public static extern Int32 WriteProcessMemory(int hProcess, int lpBaseAddress, byte[] buffer,int size,int lpNumberOfBytesWritten );
      
        //创建线程
        [DllImport("kernel32", EntryPoint = "CreateRemoteThread")]
        public static extern int CreateRemoteThread(int hProcess, int lpThreadAttributes,int dwStackSize, int lpStartAddress, int lpParameter,int dwCreationFlags, ref int lpThreadId);

        //开辟指定进程的内存空间
        [DllImport("Kernel32.dll")]
        public static extern System.Int32 VirtualAllocEx(System.IntPtr hProcess,System.Int32 lpAddress,System.Int32 dwSize,System.Int16 flAllocationType, System.Int16 flProtect );

        [DllImport("Kernel32.dll")]
        public static extern System.Int32 VirtualAllocEx( int hProcess,int lpAddress,int dwSize, int flAllocationType,int flProtect);
       
        //弹窗口
        [DllImport("user32.dll")]
        public static extern int MessageBoxA(int h, string m, string c, int type);

        //释放内存空间
        [DllImport("Kernel32.dll")]
        public static extern System.Int32 VirtualFreeEx(int hProcess,int lpAddress,int dwSize,int flAllocationType);      
     
        // 安装钩子  
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        // 卸载钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern bool UnhookWindowsHookEx(int idHook);
        // 继续下一个钩子
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

        //当前模块句柄:GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName)
        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        //声明定义回调函数
        delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);

       //CwpStruct cwpStruct = new CwpStruct();
       //static int LVM_FIRST = 0x1000;
       //static int LVM_INSERTITEMA = LVM_FIRST + 7;
       //static int LVM_SETITEMTEXT = LVM_FIRST + 46;
       //////////
       public const int WH_CALLWNDPROC = 4; //mouse hook constant
       public const int LVM_FIRST = 0x1000;
       public const int LVM_INSERTITEM = LVM_FIRST + 7;//1列     
       public const int LVM_INSERTITEMW = LVM_FIRST + 77;//1列
       public const int LVM_SETITEMTEXT = LVM_FIRST + 46;//2列
       public const int LVM_SETITEMTEXTW = LVM_FIRST + 116;//2列
       HookProc MouseHookProcedure; //Declare MouseHookProcedure as HookProc type.
       /// <summary>
       /// 委托
       /// </summary>
       /// <param name="nCode">钩子类型</param>
       /// <param name="wParam"></param>
       /// <param name="lParam"></param>
       /// <returns></returns>
       public int WarningMsg(int nCode, Int32 wParam, IntPtr lParam)
        {
            tagCWPSTRUCT lp = (tagCWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(tagCWPSTRUCT));
        
            if (lp.message == LVM_INSERTITEM || lp.message == LVM_INSERTITEMW)
            {               
               
                MessageBoxA(0, "范围是A!", "描述", 0);
              
            }
            else if (lp.message == LVM_SETITEMTEXT || lp.message == LVM_SETITEMTEXTW)
            {            
                MessageBoxA(0, "范围是B!", "描述", 0);
       
            }

            //tagCWPSTRUCT msg = (tagCWPSTRUCT)Marshal.PtrToStructure((IntPtr)lParam, typeof(tagCWPSTRUCT));              
            //if (msg.message == LVM_SETITEMTEXT)
            //{
            //    MessageBoxA(0, "取数据成功!", "描述", 0);
            //}
                //try
            {           

                /*
                tagCWPSTRUCT msg = (tagCWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(tagCWPSTRUCT));              
                IntPtr loginHwnd = AnShieldClassLibrary.WanGuaClass.FindWindow(null, "MyList"); //找到窗口句柄  
                IntPtr ListHwnd = IntPtr.Zero;
                IntPtr listThreadId =IntPtr .Zero;

                if (loginHwnd != IntPtr.Zero)
                {
                    ListHwnd = AnShieldClassLibrary.WanGuaClass.FindWindowEx(loginHwnd, IntPtr.Zero, "SysListView32", null);//列表句柄
                    GetWindowThreadProcessId(ListHwnd, ref  listThreadId);
                  
                   // tagCWPSTRUCT msg = (tagCWPSTRUCT)Marshal.PtrToStructure(lParam, typeof(tagCWPSTRUCT));
                   
                    //if (msg.message == LVM_FIRST)
                    //{
                    //    //LVITEM pLvitem = (LVITEM)cwpStruct;
                    //    //MessageBoxA(0, "取数据成功!", "描述", 0);
                    //}
                    //if (msg.message == LVM_SETITEMTEXT)
                    //{
                    //    MessageBoxA(0, "取数据成功!", "描述", 0);
                    //}
                    
                     if (msg.hwnd == ListHwnd)
                    {
                                              
                            ////内容
                            if (msg.message == Lvm_First)
                            {
                                MessageBoxA(0, "消息取得成功!", "描述", 0);
                            
                            }
                            else
                            {
                                MessageBoxA(0, "成功!", "描述", 0);
                             
                            }                     
                    }
                    else
                    {                      
                      
                         MessageBoxA(0, "消息取得成功!", "描述", 0);MessageBoxA(0, "目标线程:"+listThreadId+";;loginHwnd:" + loginHwnd + "  message:" + msg.message + "  hwnd:" + msg.hwnd +"  msg"+msg+ "  (nCode:"+nCode+" wParam:"+wParam+" LParam:"+lParam+")", "描述", 0);
                      
                    }
                }
                 * */              
                //return CallNextHookEx(warningHook, nCode, wParam, lParam);
            }
            //catch ( Exception ex) {
                //MessageBoxA(0, ex.ToString(), "错误信息", 0);
                return CallNextHookEx(warningHook, nCode, wParam, lParam);
            //}            
        }

    
      
       
        // 安装钩子
        public int Start()
        {
           
                if (warningHook == 0)
                {
                    //IntPtr loginHwnd = AnShieldClassLibrary.WanGuaClass.FindWindow(null, "MyList"); //找到窗口句柄  
                    //if (loginHwnd != IntPtr.Zero)
                    {
                        //IntPtr ListHwnd = AnShieldClassLibrary.WanGuaClass.FindWindowEx(loginHwnd, IntPtr.Zero, "SysListView32", null);//列表句柄
                       // if (ListHwnd != IntPtr.Zero)
                        {
                            //WH_CALLWNDPROC = 4 
                            IntPtr lockHwnd = Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]);
                            warningHook = SetWindowsHookEx(4, new HookProc(WarningMsg), lockHwnd, 0);// // 安装钩子    
                            //warningHook = SetWindowsHookEx(4, new HookProc(WarningMsg), GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);
                        }

                    }

                }
          
            return warningHook;
        }

        // 卸载钩子  
        public bool Stop()
        {
            bool b = false;
            if (warningHook != 0)
            {
                b= UnhookWindowsHookEx(warningHook);
            }
            return b;
        }
    }
}

//网上都说,我的朋友也说C#不能实现全局钩子获得listView之类的消息,只能实现全局的键盘和鼠标钩子,上面代码是在做得到其它程序的listView控件中的列表写的,不过没实现,项目只做了一半放下了,改其它方法实现了,本代码只供参考学习,如果哪位高手朋友做出来了,请把代码发一下,本人会非常感谢,再感谢的!!

 

抱歉!评论已关闭.