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

在.net 2005 下全局钩子的有关问题

2012-02-22 
在.net 2005 下全局钩子的问题在2003下钩子函数可以正常的使用。但是放到2005下就会出错,在运行但不调试的

在.net 2005 下全局钩子的问题
在2003下钩子函数可以正常的使用。但是放到2005下就会出错,在运行但不调试的情况下不会出错。在调试并运行的情况下就会出错,大家谁知道是为什么?怎么解决?

[解决办法]

在.NET中用全局的钩子是会出错的.

这都是老问题了,全局的钩子在.NET环境下并不好用.不是全局的倒是可以使用的.这是.NET特性决定的.
如果一定要使用全局的钩子的话,可以用非托管的DLL程序来实现,比如用VC写一个标准的Win32的或MFC的DLL,然后在用.NET调用这个DLL.

因为全局钩子一定要在非托管的DLL中才能很好的发挥作用.
关于用非托管的DLL来实现全局钩子的例子,在codeproject里有,楼主可以找一下.

[解决办法]
MSDN上的技术文章:

Knowledge Base

HOW TO: Set a Windows Hook in Visual C# .NET
PSS ID Number: 318804

Article Last Modified on 2/10/2003


--------------------------------------------
Microsoft .NET Framework SDK 1.0
Microsoft Visual C# .NET (2002)

--------------------------------------------
SUMMARY

*Set a Mouse Hook
*Global Hook Is Not Supported in .NET Framework
REFERENCES
SUMMARY
This article describes how to set a hook that is specific to a thread and to a hook procedure by using the mouse hook as an example. You can use hooks to monitor certain types of events. You can associate these events with a specific thread or with all of the threads in the same desktop as a calling thread.

Set a Mouse Hook
To set a hook, call the SetWindowsHookEx function from the User32.dll file. This function installs an application-defined hook procedure in the hook chain that is associated with the hook.

To set a mouse hook and to monitor the mouse events, follow these steps:
Start Microsoft Visual Studio .NET.
On the File menu, point to New, and then click Project.
In the New Project dialog box, click Visual C# Projects under Project Types, and then click Windows Application under Templates. In the Name box, type ThreadSpecificMouseHook. Form1 is added to the project by default.
Add the following line of code in the Form1.cs file after the other using statements:
using System.Runtime.InteropServices;

Add following code in the Form1 class:
public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

//Declare hook handle as int.
static int hHook = 0;

//Declare mouse hook constant.
//For other hook types, you can obtain these values from Winuser.h in Microsoft SDK.
public const int WH_MOUSE = 7;
private System.Windows.Forms.Button button1;

//Declare MouseHookProcedure as HookProc type.
HookProc MouseHookProcedure;

//Declare wrapper managed POINT class.
[StructLayout(LayoutKind.Sequential)]
public class POINT
{
public int x;
public int y;
}

//Declare wrapper managed MouseHookStruct class.
[StructLayout(LayoutKind.Sequential)]
public class MouseHookStruct
{
public POINT pt;
public int hwnd;
public int wHitTestCode;
public int dwExtraInfo;
}

//Import for SetWindowsHookEx function.
//Use this function to install thread-specific hook.
[DllImport( "user32.dll ",CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn,
IntPtr hInstance, int threadId);

//Import for UnhookWindowsHookEx.
//Call this function to uninstall the hook.
[DllImport( "user32.dll ",CharSet=CharSet.Auto,
CallingConvention=CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);

//Import for CallNextHookEx.
//Use this function to pass the hook information to next hook procedure in chain.
[DllImport( "user32.dll ",CharSet=CharSet.Auto,


CallingConvention=CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode,
IntPtr wParam, IntPtr lParam);

Add a Button control to the form, and then add the following code in the Button1_click procedure:
private void button1_Click(object sender, System.EventArgs e)
{
if(hHook == 0)
{
// Create an instance of HookProc.
MouseHookProcedure = new HookProc(Form1.MouseHookProc);

hHook = SetWindowsHookEx(WH_MOUSE,
MouseHookProcedure,
(IntPtr)0,
AppDomain.GetCurrentThreadId());
//If SetWindowsHookEx fails.
if(hHook == 0 )
{
MessageBox.Show( "SetWindowsHookEx Failed ");
return;
}
button1.Text = "UnHook Windows Hook ";
}
else
{
bool ret = UnhookWindowsHookEx(hHook);
//If UnhookWindowsHookEx fails.
if(ret == false )
{
MessageBox.Show( "UnhookWindowsHookEx Failed ");
return;
}
hHook = 0;
button1.Text = "Set Windows Hook ";
this.Text = "Mouse Hook ";
}
}

Add the following code for the MouseHookProc function in the Form1 class:
public static int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
//Marshall the data from callback.
MouseHookStruct MyMouseHookStruct = (MouseHookStruct) Marshal.PtrToStructure(lParam, typeof(MouseHookStruct));

if (nCode < 0)
{
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
else
{
//Create a string variable with shows current mouse. coordinates
String strCaption = "x = " +
MyMouseHookStruct.pt.x.ToString( "d ") +
" y = " +
MyMouseHookStruct.pt.y.ToString( "d ");
//Need to get the active form because it is a static function.
Form tempForm = Form.ActiveForm;

//Set the caption of the form.
tempForm.Text = strCaption;
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
}

Press F5 to run the project, and then click the button on the form to set the hook. The mouse coordinates appear on the form caption bar when the pointer moves on the form. Click the button again to remove the hook.
back to the top
Global Hook Is Not Supported in .NET Framework
You cannot implement global hooks in Microsoft .NET Framework. To install a global hook, a hook must have a native dynamic-link library (DLL) export to inject itself in another process that requires a valid, consistent function to call into. This requires a DLL export, which .NET Framework does not support. Managed code has no concept of a consistent value for a function pointer because these function pointers are proxies that are built dynamically.

REFERENCES
For more information about windows hooks, see the following MSDN documentation:
About Hooks
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/hooks_9rg3.asp

热点排行