首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

上贴没说清楚有关问题,还是线程钩子有关问题?

2012-01-19 
上贴没说清楚问题,还是线程钩子问题??????????????????????????全局钩子一点问题也没有,线程钩子就要报错。

上贴没说清楚问题,还是线程钩子问题??????????????????????????
全局钩子一点问题也没有,线程钩子就要报错。
按照下面的代码,线程钩子,金山词霸进程里的其中一个线程。
报错: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,如果是金山词霸,就钩之.
[解决办法]
你不相信微软的文档我也没办法了

热点排行