上贴没说清楚问题,还是线程钩子问题??????????????????????????
全局钩子一点问题也没有,线程钩子就要报错。
按照下面的代码,线程钩子,金山词霸进程里的其中一个线程。
报错:xdict.exe 中的 0x01f73772 处未处理的异常: 0xC0000005: 写入位置 0x00000000 时发生访问冲突。
为什么全局钩子就没有问题,线程钩子就要报错呢?各位高手指教啊,谢谢,非常感谢。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace WindowsApplication3
{
public partial class Form1 : Form
{
[DllImport( "user32.dll ", EntryPoint = "SetWindowsHookEx ", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowsHookEx(int idHook, ClassLibrary2.HookCallBack lpfn, IntPtr hMod, int dwThreadId);
public Form1()
{
InitializeComponent();
}
int threadid=0;
const int WH_GETMESSAGE = 3;
private void button1_Click(object sender, EventArgs e)
{
Process[] proe = Process.GetProcesses();
foreach (Process proc in proe)//遍历所有进程
{
foreach (ProcessThread var in proc.Threads) //得到进程的所有线程
{
if (proc.ProcessName == "xdict ") //如果是金山词霸进程。
{
threadid = var.Id; //得到其中一个线程
break;
}
listBox1.Items.Add(proc.ProcessName + " " + var.Id);
}
}
ClassLibrary2.Class1 cl1=new ClassLibrary2.Class1();
cl1.hookhandle = SetWindowsHookEx(WH_GETMESSAGE, cl1.hookcallback, Marshal.GetHINSTANCE(Assembly.GetAssembly(cl1.GetType()).GetModule( "ClassLibrary2.dll ")), threadid);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;
namespace ClassLibrary2
{
public delegate int HookCallBack(int ncode, IntPtr wParam, IntPtr iParam);
public class Class1
{
public const int WH_KEYBOARD = 2;
public const int WM_KEYDOWN = 0x0100;
[DllImport( "user32.dll ", EntryPoint = "FindWindow ", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport( "user32.dll ", EntryPoint = "SendMessage ", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport( "user32.dll ", EntryPoint = "SetWindowsHookEx ", CharSet = CharSet.Auto)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookCallBack lpfn, IntPtr hMod, int dwThreadId);
[DllImport( "user32.dll ", EntryPoint = "CallNextHookEx ", CharSet = CharSet.Auto)]
public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport( "user32.dll ", EntryPoint = "UnhookWindowsHookEx ", CharSet = CharSet.Auto)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
public HookCallBack hookcallback;
public IntPtr hookhandle = IntPtr.Zero;
public Class1()
{
hookcallback = new HookCallBack(messagecallback);
}
public int messagecallback(int ncode, IntPtr wParam, IntPtr iParam)
{
return CallNextHookEx(hookhandle, ncode, wParam, iParam);
}
}
}
[解决办法]
.Net 除了WH_KEYBOARD_LL和WH_MOUSE_LL这两个以外,其他的钩子都只能钩自己的进程.
换句话说,.Net没办法去钩金山词霸,除非是WH_KEYBOARD_LL和WH_MOUSE_LL.
要实现你的需求.
1.用C++来写,其实这些与Win32 API打交到的程序,用C++方便的多,#include <windows.h> ,你就能随便使用API函数了.
2.使用WH_KEYBOARD_LL和WH_MOUSE_LL这两个钩子,每次判断ActiveWindow,如果是金山词霸,就钩之.
[解决办法]
你不相信微软的文档我也没办法了