SetWindowsHookEx在Net 2中有效,但在Net 4中无效 [英] SetWindowsHookEx works in Net 2 but not in Net 4

查看:83
本文介绍了SetWindowsHookEx在Net 2中有效,但在Net 4中无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个将与条形码扫描仪配合使用的应用程序,即使该应用程序不是活动的应用程序,也不是来自应用程序内部的单独线程,都需要侦听输入.设置 专为Net 2编译的项目.当我将项目设置为针对Net 4编译时,无法从SetWindowsHookEx获取句柄.相同的代码,完全没有更改.虽然显然我可以从中得到一个有效的DLL,但实际上是____的错误. 我.此外,如果我的一位同事将来需要调整此DLL而又不知道,则可以在Net 4中对其进行编译.我也不知道如果我在Net 4中编译的另一个项目中引用此DLL会产生什么影响. 最后,我担心如果我不知道有什么区别,将来可能会遇到更多类似的困难.有谁知道这是为什么或解决方案是什么?

I am developing an application that will engage a bar code scanner and will need to be listening for input even when it is not the active application or from a separate thread from within the application.  I can get a handle to the hook when I set the project to compile for Net 2.  When I set my project to compile for Net 4 I cannot get a handle from the SetWindowsHookEx.  Same code, no changes at all.  While obviously I can get a working DLL out of this it really is buggin the ____ out of me.  Additionally, if one of my colegues needs to adjust this DLL in the future and does not know, they may compile it in Net 4.  I also have no idea what will be the effects if I reference this DLL in another project that is compiled in Net 4.  Lastly, I am worried that I may encounter more difficulties like this in the future if I cannot figure out what the difference is.  Does anyone know why this is or what the solution might be?

Emory

 

< code>

<code>

导入System.Reflection
导入System.Runtime.InteropServices
导入System.Threading
导入System.Windows.Forms

公共类KeyboardKeyEventListener
   实现IDisposable

#Region"成员"

   私有枚举HookType为整数
        WH_JOURNALRECORD = 0
        WH_JOURNALPLAYBACK = 1
        WH_KEYBOARD = 2
        WH_GETMESSAGE = 3
        WH_CALLWNDPROC = 4
        WH_CBT = 5
        WH_SYSMSGFILTER = 6
        WH_MOUSE = 7
        WH_HARDWARE = 8
        WH_DEBUG = 9
        WH_SHELL = 10
        WH_FOREGROUNDIDLE = 11
        WH_CALLWNDPROCRET = 12
        WH_KEYBOARD_LL = 13
        WH_MOUSE_LL = 14
   结束枚举

    '//指示低级别键盘消息的代码
   私有常量WH_KEYBOARD_LL作为整数= 13&

    '//低级键盘常量
   私有常量HC_ACTION为整数= 0
   私有常量LLKHF_EXTENDED为Integer =& H1
   私有常量LLKHF_INJECTED为Integer =& H10
   私有常量LLKHF_ALTDOWN为整数=& H20
   私有常量LLKHF_UP为Integer =& H80

    '//KeyUp/KeyDown常量
   私有常量WM_KEYDOWN为整数=& H100
   私有常量WM_KEYUP作为整数=& H101
   私有常量WM_SYSKEYDOWN为整数=& H104
   私有常量WM_SYSKEYUP为Integer =& H105

    '//变量
   专用KeyboardHandle作为整数
   私有处置为Boolean = False

    '//Marshal是Windows在发送键事件时防止GC恢复我们的委托并创建空引用所必需的.
    < MarshalAs(UnmanagedType.FunctionPtr)>专用KeyboardHookProcedure为KeyboardHookDelegate =新的KeyboardHookDelegate(AddressOf ProcessKeyboardMessage)

#End Region

#Region"活动"

   公共事件KeyDown(由Windows将Form.KeyEventArgs引用给KeyArgs)
   公共事件KeyPress(由Windows窗体的KeyEventArgs引用TheKeyArgs)
   公共事件KeyUp(由Windows窗体的KeyEventArgs引用TheKeyArgs)

#End Region

#Region"代表"

   私人代表功能KeyboardHookDelegate(按Val的整数代码,_
              nbsp; bsp               nbsp; bsp ByVal WParam As Integer,_
              nbsp; bsp               nbsp; bsp ByRef LParam作为KBDLLHOOKSTRUCT)作为整数

#End Region

#Region" 'user32.dll'的功能声明"

   私有声明函数UnhookWindowsHookEx Lib"user32" (ByVal hHook为Integer)为Integer

   私有声明函数SetWindowsHookEx Lib"user32"别名"SetWindowsHookExA"; (ByVal idHook为整数,_
              nbsp; bsp               nbsp; bsp               nbsp; bsp           ByVal lpfn作为KeyboardHookDelegate,_
              nbsp; bsp               nbsp; bsp               nbsp; bsp           ByVal hmod As Integer,_
              nbsp; bsp               nbsp; bsp               nbsp; bsp           ByVal dwThreadId(作为整数)作为Integer

   私有声明函数GetAsyncKeyState Lib"user32" (ByVal vKey为Integer)为Integer

   私有声明函数CallNextHookEx Lib"user32" (ByVal hHook为整数,_
              nbsp; bsp               nbsp; bsp        ByVal nCode As Integer,_
              nbsp; bsp               nbsp; bsp        ByVal wParam As Integer,_
              nbsp; bsp               nbsp; bsp        ByVal lParam作为KBDLLHOOKSTRUCT)作为整数

#End Region

#Region"结构"

   私有结构KBDLLHOOKSTRUCT
      公开vkCode为整数
      公用scanCode为整数
      公开标志为Integer
      公开时间为整数
      将dwExtraInfo公开为整数
   端部结构

#End Region

#Region"构造函数,析构函数和加载方法"

    Public Sub New()

      试试

      异常捕获
          扔前
      结束尝试

   结束子

   公共重写Sub Dispose()实现IDisposable.Dispose

      试试
          如果没有(处置=真),则
                            处置=真实
                            如果不是(KeyboardHandle = 0),则取消钩子WindowsHookEx(KeyboardHandle)
          其他
                            引发New ObjectDisposedException("KeyboardHook")
          如果结束

      异常捕获
          扔前
      结束尝试

   结束子

   受保护的重写Sub Finalize()

      试试
           MyBase.Finalize()

          如果不处理的话
                             Dispose()
          如果结束

      异常捕获
          扔前
      结束尝试

   结束子

#End Region

#Region"方法-主要"

   公共函数StartListening()为布尔值

      试试
           '//SetWindowsHookEx的第一个参数设置挂钩的类型.
           '//第二个参数是带标签的委托,其中包含我们本地回调方法的地址.
           '//第三个参数是执行挂接的应用程序的句柄(hWnd)
           '//第四个参数是要监听的线程.传递0表示所有线程.

           Console.WriteLine(" KeyboardHandle =" + KeyboardHandle.ToString)
           Console.WriteLine("WH_KEYBOARD_LL =" + WH_KEYBOARD_LL.ToString)
           Console.WriteLine(" KeyboardHookProcedure =" + KeyboardHookProcedure.ToString)
           Console.WriteLine(当前程序集线程=" + Marshal.GetHINSTANCE([Assembly] .GetExecutingAssembly.GetModules()(0)).ToInt32.ToString)
           Console.WriteLine(")

           KeyboardHandle = SetWindowsHookEx(WH_KEYBOARD_LL,_
              nbsp; bsp               KeyboardHookProcedure,_
              nbsp; bsp               元帅.GetHINSTANCE([Assembly] .GetExecutingAssembly.GetModules()(0)).ToInt32,_
              nbsp; bsp               0)

           Console.WriteLine(" KeyboardHandle =" + KeyboardHandle.ToString)

          如果(KeyboardHandle = 0)那么
                            返回False
          其他
                            返回True
          如果结束

      异常捕获
          引发新异常(``StartListening中遇到异常''+ vbCrLf + ex.Message)
      结束尝试

   结束功能

   公共函数StopListening()为布尔值

      试试
          如果不是(KeyboardHandle = 0),则取消钩子WindowsHookEx(KeyboardHandle)

           Console.WriteLine(KeyboardHandle.ToString)
           KeyboardHandle = 0

          返回True

      异常捕获
          扔前
      结束尝试

   结束功能

   私有函数ProcessKeyboardMessage(ByVal代码为整数,ByVal WParam为整数,ByRef LParam为KBDLLHOOKSTRUCT)作为整数

      试试
          将TheKeys设置为Windows.Forms.Keys = CType(LParam.vkCode,Keys)
          将TheKeyArgs变暗为Windows.Forms.KeyEventArgs =新的Windows.Forms.KeyEventArgs(TheKeys)

          如果WParam = WM_KEYDOWN或WParam = WM_SYSKEYDOWN那么
                             RaiseEvent KeyDown(TheKeyArgs)
          其他如果WParam = WM_KEYUP或WParam = WM_SYSKEYUP那么
                             RaiseEvent KeyUp(TheKeyArgs)
          如果结束

           '//调用钩子链中的下一个钩子并返回值
          返回CallNextHookEx(KeyboardHandle,Code,WParam,LParam)

      异常捕获
          引发新异常(``ProcessKeyStroke中遇到异常''+ vbCrLf + vbCrLf + ex.Message)
      结束尝试

   结束功能

#End Region

#Region"方法-实用程序"

#End Region

结束类

</code>

Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Threading
Imports System.Windows.Forms

Public Class KeyboardKeyEventListener
    Implements IDisposable

#Region " Members "

    Private Enum HookType As Integer
         WH_JOURNALRECORD = 0
         WH_JOURNALPLAYBACK = 1
         WH_KEYBOARD = 2
         WH_GETMESSAGE = 3
         WH_CALLWNDPROC = 4
         WH_CBT = 5
         WH_SYSMSGFILTER = 6
         WH_MOUSE = 7
         WH_HARDWARE = 8
         WH_DEBUG = 9
         WH_SHELL = 10
         WH_FOREGROUNDIDLE = 11
         WH_CALLWNDPROCRET = 12
         WH_KEYBOARD_LL = 13
         WH_MOUSE_LL = 14
    End Enum

    '// The Code Indicating Low Level Keyboard Message
    Private Const WH_KEYBOARD_LL As Integer = 13&

    '// Low-Level Keyboard Constants
    Private Const HC_ACTION As Integer = 0
    Private Const LLKHF_EXTENDED As Integer = &H1
    Private Const LLKHF_INJECTED As Integer = &H10
    Private Const LLKHF_ALTDOWN As Integer = &H20
    Private Const LLKHF_UP As Integer = &H80

    '// KeyUp/KeyDown Constants
    Private Const WM_KEYDOWN As Integer = &H100
    Private Const WM_KEYUP As Integer = &H101
    Private Const WM_SYSKEYDOWN As Integer = &H104
    Private Const WM_SYSKEYUP As Integer = &H105

    '// Variables
    Private KeyboardHandle As Integer
    Private Disposed As Boolean = False

    '// MarshalAs required to keep GC from recovering our delegate and creating a null reference when Windows sends the key event.
    <MarshalAs(UnmanagedType.FunctionPtr)> Private KeyboardHookProcedure As KeyboardHookDelegate = New KeyboardHookDelegate(AddressOf ProcessKeyboardMessage)

#End Region

#Region " Events "

    Public Event KeyDown(ByRef TheKeyArgs As Windows.Forms.KeyEventArgs)
    Public Event KeyPress(ByRef TheKeyArgs As Windows.Forms.KeyEventArgs)
    Public Event KeyUp(ByRef TheKeyArgs As Windows.Forms.KeyEventArgs)

#End Region

#Region " Delegates "

    Private Delegate Function KeyboardHookDelegate(ByVal Code As Integer, _
                                                   ByVal WParam As Integer, _
                                                   ByRef LParam As KBDLLHOOKSTRUCT) As Integer

#End Region

#Region " Function Declarations for 'user32.dll' "

    Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer

    Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, _
                                                                                      ByVal lpfn As KeyboardHookDelegate, _
                                                                                      ByVal hmod As Integer, _
                                                                                      ByVal dwThreadId As Integer) As Integer

    Private Declare Function GetAsyncKeyState Lib "user32" (ByVal vKey As Integer) As Integer

    Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Integer, _
                                                          ByVal nCode As Integer, _
                                                          ByVal wParam As Integer, _
                                                          ByVal lParam As KBDLLHOOKSTRUCT) As Integer

#End Region

#Region " Structures "

    Private Structure KBDLLHOOKSTRUCT
        Public vkCode As Integer
        Public scanCode As Integer
        Public flags As Integer
        Public time As Integer
        Public dwExtraInfo As Integer
    End Structure

#End Region

#Region " Constructors, Destructors and Load Methods "

    Public Sub New()

        Try

        Catch ex As Exception
            Throw ex
        End Try

    End Sub

    Public Overridable Sub Dispose() Implements IDisposable.Dispose

        Try
            If Not (Disposed = True) Then
                Disposed = True
                If Not (KeyboardHandle = 0) Then UnhookWindowsHookEx(KeyboardHandle)
            Else
                Throw New ObjectDisposedException("KeyboardHook")
            End If

        Catch ex As Exception
            Throw ex
        End Try

    End Sub

    Protected Overrides Sub Finalize()

        Try
            MyBase.Finalize()

            If Not Disposed Then
                Dispose()
            End If

        Catch ex As Exception
            Throw ex
        End Try

    End Sub

#End Region

#Region " Methods - Primary "

    Public Function StartListening() As Boolean

        Try
            '// The first argument to SetWindowsHookEx Sets the Type of Hook.
            '// The second argument is the tagged delegate that contains the address of our local callback method.
            '// The third argument is the handle (hWnd) of the application doing the hooking
            '// The fourth argument is the thread to listen on.  Passing 0 indicates all threads.

            Console.WriteLine("KeyboardHandle = " + KeyboardHandle.ToString)
            Console.WriteLine("WH_KEYBOARD_LL = " + WH_KEYBOARD_LL.ToString)
            Console.WriteLine("KeyboardHookProcedure = " + KeyboardHookProcedure.ToString)
            Console.WriteLine("Current Assembly Thread = " + Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32.ToString)
            Console.WriteLine("")

            KeyboardHandle = SetWindowsHookEx(WH_KEYBOARD_LL, _
                                              KeyboardHookProcedure, _
                                              Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, _
                                              0)

            Console.WriteLine("KeyboardHandle = " + KeyboardHandle.ToString)

            If (KeyboardHandle = 0) Then
                Return False
            Else
                Return True
            End If

        Catch ex As Exception
            Throw New Exception("Exception encountered in StartListening" + vbCrLf + ex.Message)
        End Try

    End Function

    Public Function StopListening() As Boolean

        Try
            If Not (KeyboardHandle = 0) Then UnhookWindowsHookEx(KeyboardHandle)

            Console.WriteLine(KeyboardHandle.ToString)
            KeyboardHandle = 0

            Return True

        Catch ex As Exception
            Throw ex
        End Try

    End Function

    Private Function ProcessKeyboardMessage(ByVal Code As Integer, ByVal WParam As Integer, ByRef LParam As KBDLLHOOKSTRUCT) As Integer

        Try
            Dim TheKeys As Windows.Forms.Keys = CType(LParam.vkCode, Keys)
            Dim TheKeyArgs As Windows.Forms.KeyEventArgs = New Windows.Forms.KeyEventArgs(TheKeys)

            If WParam = WM_KEYDOWN Or WParam = WM_SYSKEYDOWN Then
                RaiseEvent KeyDown(TheKeyArgs)
            ElseIf WParam = WM_KEYUP Or WParam = WM_SYSKEYUP Then
                RaiseEvent KeyUp(TheKeyArgs)
            End If

            '// Call the next hook in the hook chain and return the value
            Return CallNextHookEx(KeyboardHandle, Code, WParam, LParam)

        Catch ex As Exception
            Throw New Exception("Exception encountered in ProcessKeyStroke" + vbCrLf + vbCrLf + ex.Message)
        End Try

    End Function

#End Region

#Region " Methods - Utility "

#End Region

End Class

</code>

 

推荐答案

.Net 4.0调用失败时存在相同的问题.有什么建议?指针?

Having same issue in .Net 4.0 call failing. Any suggestions? Pointers?

预先感谢.


这篇关于SetWindowsHookEx在Net 2中有效,但在Net 4中无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆