2010-08-23 6 views
1

J'utilise this sample comme base pour un programme que je fais. Après environ 618 frappes, le programme lance cette erreur:Programme émet des erreurs au hasard (vb.net)

CallbackOnCollectedDelegate was detected 
Message: A callback was made on a garbage collected delegate of type 'KeyLogger!KeyLogger.CallBackFunction+DelegateCallBack::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called. 

L'erreur est renvoyée la plupart du temps l'application est exécutée, mais pas à chaque fois et pas au même nombre de touches. À partir du message d'erreur, je pense qu'il semble que le garbage collector collecte le délégué, comment puis-je l'empêcher?

Le programme que j'ai créé est essentiellement une version modifiée de ce projet vb.net, mais il ne stocke pas réellement les séquences de touches.

Nous vous remercions de votre aide!

Code dans CallBack.vb:

Option Strict Off 
Option Explicit On 
Module CallBackFunction 
    '****************************************************************************************** 
    '  Sample for retrieving keystrokes by use of the "kbLog32.dll" 
    '      (c) 2004 by Nadeem Afanah. 
    '****************************************************************************************** 

    'CallBack function 
    Delegate Sub DelegateCallBack(ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) 

    Sub CallBack(ByVal msg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) 
     'here we track only WM_CHAR and WM_KEYDOWN 
     If msg = WM_KEYDOWN Then 
      ...  
     End If 
    End Sub 
End Module 

code dans Declarations.vb:

Option Strict Off 
Option Explicit On 
Module Declarations 
    '****************************************************************************************** 
    '  Sample for retrieving keystrokes by use of the "kbLog32.dll" 
    '      (c) 2004 by Nadeem Afanah. 
    '****************************************************************************************** 
    '****************************************************************************************** 
    'DLL declarations 
    Public Declare Function StartLog Lib "kbLog32" (ByVal hWnd As Integer, ByVal lpFuncAddress As DelegateCallBack) As Integer 

    Public Declare Sub EndLog Lib "kbLog32"() 

    '---------------------------------------------------------------------------------------- 
    Declare Function SetWindowPos Lib "user32" (ByVal hWnd As Integer, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer 
    Declare Function FindWindow Lib "user32" Alias "FindWindowA"(ByVal lpClassName As String, ByVal lpWindowName As String) As Integer 
    Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA"(ByVal hWnd1 As Integer, ByVal hWnd2 As Integer, ByVal lpsz1 As String, ByVal lpsz2 As String) As Integer 
    '**************************************************************************************** 
    ' Keyboard messages 
    Public Const WM_KEYUP As Short = &H101s 
    Public Const WM_KEYDOWN As Short = &H100s 
    Public Const WM_CHAR As Short = &H102s 
    Public Const WM_SYSKEYDOWN As Short = &H104s 
    Public Const WM_SYSKEYUP As Short = &H105s 

    'SetWindowPos messages 
    Public Const SWP_NOSIZE As Short = &H1s 
    Public Const SWP_NOMOVE As Short = &H2s 
    Public Const HWND_TOPMOST As Short = -1 
    Public Const SWP_SHOWWINDOW As Short = &H40s 
    '****************************************************************************************** 

End Module 
+0

N'hésitez pas à changer le titre aro und, ce n'est pas très descriptif et je m'excuse pour ça. – Cyclone

+0

Je pense que plus d'informations sont nécessaires. * (IE: code) * – ChaosPandion

+0

Regardez les révisions, j'avais un lien HTML mais je suppose que les liens html ne sont plus autorisés. J'utilise maintenant la démarque pour le lien. – Cyclone

Répondre

3

Regardez le code Form1.vb où il le fait:

StartLog(nhWnd_text, AddressOf CallBack) 

C'est là où il est dit, prendre l'emplacement de la fonction de rappel et l'utiliser pour récupérer les messages que je reçois concernant l'événement clavier s.

Essayez quelque chose comme ceci:

Friend Class Form1 
    Inherits System.Windows.Forms.Form 
    ''Add this ---------------------------- 
    <MarshalAs(UnmanagedType.FunctionPtr)> _ 
    Private DelSub as New DelegateCallBack(AdressOf CallBack) 
    ''------------------------------------- 

    ''In the sub Sub Command1_Click 
    ''Change this ------------------------- 
     StartLog(nhWnd_text, AddressOf CallBack) 
    ''To this ----------------------------- 
     StartLog(nhWnd_text, DelSub) 
    ''------------------------------------- 

End Class 

Ce que nous faisons ici est la création d'un « sous-délégué » local (penser comme une variable qui pointe à un sous). Nous indiquons ceci au sous-alinéa Callback. Nous utilisons ensuite ce sous-délégué au lieu de passer directement une référence au sous-champ Callback.

La différence est que le framework .Net sait maintenant qu'il ya pointage quelque chose à ce sous ne sera donc pas des ordures recueillir (l'effacer de la mémoire)

Le bit MarshallAs est un peu superflu car c'est la valeur par défaut marshalling mais cela signifie simplement que nous disons explicitement .Net que nous utilisons le délégué pour accéder au code non managé (quelque chose en dehors du framework .Net)

Juste pour l'enregistrement, je devais encore télécharger le code tel qu'il était en fait, le bit dans Form1.vb qui était pertinent - Mais merci d'essayer :)

+0

Mon explication a glissé sur quelques bits, mais vous pouvez obtenir plus d'informations à partir du lien que j'ai posté dans les commentaires sur la question – Basic

+0

Travailler jusqu'à présent. Exécuter une série de tests et vous faire connaître les résultats. – Cyclone

+0

Cela a fonctionné, merci beaucoup! – Cyclone