C# 全域性鉤子 方法二
//網上都說,我的朋友也說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控制元件中的列表寫的,不過沒實現,專案只做了一半放下了,改其它方法實現了,本程式碼只供參考學習,如果哪位高手朋友做出來了,請把程式碼發一下,本人會非常感謝,再感謝的!!