Hook : pb de compatibilité .net 1.1 et 2.0

Description

Voici un code de hook Clavier + Souris devellopé en vb.net 1.1 et le même en 2.0
Avant tte remarque du style "ouin ouin ... yen a deja plein"
le but de ce post n'est pas exculsivment de montrer comment on hook mais de mettre a jour et de m'aider à résoudre un soucis a savoir :

Le code .net 1.1 tourne avec VS 2003 fonctionnent bien actuellemnt (XP pro, avec VS 2003 + VS 2005 + framework 1.1 et framework 2.0 installer sur la meme machine), le bouton "Hook/UnHook" met en route une surveillance clavier souris et le timer dans el label indique depuis combien de temps le clavier et la souris n'ont pas été utiliser (il repars a zéro des qu'on y touche) => l'IdleTime en somme. Ceci avec une limite maximal reglable dans le module a la ligne suivante :
If ((nTickActuel - nTickIdle) / (1000 * 60)) >= 15 Then
ici la limite est donc de 15 minutes

Source / Exemple :


Imports System.Runtime.InteropServices
Imports System.Reflection

Module Hook

#Region "APIs"

    Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Integer) As Integer
    Private Declare Function SetWindowsHookExClavier Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As HookClavierDelegate, ByVal hmod As Integer, ByVal dwThreadId As Integer) As Integer
    Private Declare Function SetWindowsHookExSouris Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Integer, ByVal lpfn As HookSourisDelegate, 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 CallNextHookExClavier Lib "user32" Alias "CallNextHookEx" (ByVal hHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As KBDLLHOOKSTRUCT) As Integer
    Private Declare Function CallNextHookExSouris Lib "user32" Alias "CallNextHookEx" (ByVal hHook As Integer, ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer

#End Region

#Region "Structures et Constantes"

    Private Structure POINT
        Private x As Integer
        Private y As Integer
    End Structure
    Private Structure MSLLHOOKSTRUCT
        Public pt As POINT
        Public mouseData As Integer
        Public flags As Integer
        Public time As Integer
        Public dwExtraInfo As Integer
    End Structure
    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
    Private Const HC_ACTION As Integer = 0
    Private Const WH_KEYBOARD_LL As Integer = 13
    Private Const WH_MOUSE_LL As Integer = 14

#End Region

#Region "Delegate"

    Private Delegate Function HookClavierDelegate(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer
    Private Delegate Function HookSourisDelegate(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer
    <MarshalAs(UnmanagedType.FunctionPtr)> Private dlgClavierCallBack As HookClavierDelegate
    <MarshalAs(UnmanagedType.FunctionPtr)> Private dlgSourisCallBack As HookSourisDelegate

#End Region

    Private hHookClavier As Integer
    Private hHookSouris As Integer
    Private WithEvents tmrSeconde As Timers.Timer
    Private nTickIdle As Integer

    Public Function Hook() As Boolean
        Dim hInstance As Integer

        dlgClavierCallBack = New HookClavierDelegate(AddressOf ClavierCallBack)
        dlgSourisCallBack = New HookSourisDelegate(AddressOf SourisCallBack)

        hInstance = Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32

        hHookClavier = SetWindowsHookExClavier(WH_KEYBOARD_LL, dlgClavierCallBack, hInstance, 0)
        hHookSouris = SetWindowsHookExSouris(WH_MOUSE_LL, dlgSourisCallBack, hInstance, 0)

        If ((hHookClavier <> 0) AndAlso (hHookSouris <> 0)) Then
            tmrSeconde = New Timers.Timer
            tmrSeconde.AutoReset = True
            tmrSeconde.Interval = 100
            nTickIdle = Environment.TickCount
            tmrSeconde.Start()
            Return True
        Else
            Return False
        End If
    End Function

    Public Sub UnHook()
        If hHookClavier <> 0 Then
            UnhookWindowsHookEx(hHookClavier)
        End If
        If hHookSouris <> 0 Then
            UnhookWindowsHookEx(hHookSouris)
        End If

        tmrSeconde.Stop()
        tmrSeconde.Close()

        hHookClavier = 0
        hHookSouris = 0

        dlgClavierCallBack = Nothing
        dlgSourisCallBack = Nothing
        tmrSeconde = Nothing
    End Sub

    Private Sub tmrSeconde_Elapsed(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs) Handles tmrSeconde.Elapsed
        Dim nTickActuel As Integer = Environment.TickCount
        'Delai de l'Idle: 20 minute
        Dim frm As Form1 = CType(Form1.ActiveForm, Form1)
        frm.Affichage(nTickActuel - nTickIdle)
        If ((nTickActuel - nTickIdle) / (1000 * 60)) >= 15 Then
            'On concidère que l'Idle est suffisant pour declenché le processus
            UnHook()
            Stop
            'EVENTS()
        End If
    End Sub

#Region "CallBack"

    Private Function ClavierCallBack(ByVal Code As Integer, ByVal wParam As Integer, ByRef lParam As KBDLLHOOKSTRUCT) As Integer

        If (Code = HC_ACTION) Then
            nTickIdle = Environment.TickCount
        End If

        Return CallNextHookExClavier(hHookClavier, Code, wParam, lParam)
    End Function

    Private Function SourisCallBack(ByVal nCode As Integer, ByVal wParam As Integer, ByVal lParam As MSLLHOOKSTRUCT) As Integer

        If (nCode = HC_ACTION) Then
            nTickIdle = Environment.TickCount
        End If

        Return CallNextHookExSouris(hHookSouris, nCode, wParam, lParam)
    End Function

#End Region

End Module

Conclusion :


Qu'est ce qui ne va pas ?
j'ai créé un nouveau projet sous VS2005 (.net 2.0) meme nom de form, de boutton, de label, de module
copier coller dans les procédures

précompilateur => 0 messages, warnings, erreurs
compilateur => 0 messages, warnings, erreurs
éxecution => 0 excpetions

travail demandé => pas fait du tout

localisation du pb :
[...]
Private hHookClavier As Integer
Private hHookSouris As Integer
[...]
hHookClavier = SetWindowsHookExClavier(WH_KEYBOARD_LL, dlgClavierCallBack, hInstance, 0)
hHookSouris = SetWindowsHookExSouris(WH_MOUSE_LL, dlgSourisCallBack, hInstance, 0)
[...]

quand le code marche "hHookClavier" et "hHookSouris" sont censé recevoir le numero du handle du hook (un identifiant système unique qui permet de savoir que ca a marcher en somme), la doc de "SetWindowsHookExA" indique :

Return Value
If the function succeeds, the return value is the handle to the hook procedure.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.

autre passage de la doc MSDN :
Visual Basic: Applications should call err.LastDllError instead of GetLastError.

ici les 2 integer resultants sont NULL, donc il c'est produit une erreur durant l'appelle, au débugage j'ai donc rajouté 2 ligne :
hHookClavier = SetWindowsHookExClavier(WH_KEYBOARD_LL, dlgClavierCallBack, hInstance, 0)
Dim nBug1 As Integer = Err.LastDllError
hHookSouris = SetWindowsHookExSouris(WH_MOUSE_LL, dlgSourisCallBack, hInstance, 0)
Dim nBug2 As Integer = Err.LastDllError

et la "nBug1" et "nBug2" sont tout les 2 égale a 0 et quoi qu'il en soit Err n'est meme pas remplis qqsoti le champs

en somme : SetWindowsHookEx dit qu'il y a une erreur et en même temps le service d'erreur windows me dit qu'il n'y en a pas.

je suis donc actuellment assez embetté, je ne sais pas ocmment résoudre ce pb :
  • Faut il changer la manière/Méthode/Syntaxe des délégué sous .net 2.0 pour le cas ici présent
  • Le handle de l'instance est il tjs correct sous .Net 2.0
  • Autre ...


enfin si qqun pouvais m'aider a résoudre ce pb ca m'aiderai bcp merci d'avance

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.