2010-08-23 89 views
1

我正在使用this sample作为我正在制作的程序的基础。在大约618按键,方案抛出这个错误:程序随机抛出错误(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. 

将引发错误的应用程序运行次数最多,但不是每一次,而不是在同一个按键计数。从错误消息中,我认为这听起来像垃圾收集器正在收集委托,我该如何防止这种情况?

我做的程序本质上是该vb.net项目的修改版本,但它并不实际存储击键。

谢谢你的帮助!内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 

守则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

随意改变标题aro这不是很具描述性,我为此道歉。 – Cyclone 2010-08-23 23:59:48

+0

我认为需要更多信息。 *(IE:代码)* – ChaosPandion 2010-08-24 00:00:02

+0

看看版本,我有一个HTML链接,但我想HTML链接不再允许。我现在使用降价链接。 – Cyclone 2010-08-24 00:04:22

回答

3

看在Form1.vb的代码在那里它这样做:

StartLog(nhWnd_text, AddressOf CallBack) 

这就是它说的地方,将回调函数的位置用来处理我收到的有关键盘事件的消息秒。

尝试这样:

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 

我们这里所做的是建立一个当地的“委托子”(认为它是指向了一个子变量)。我们在Callback小组中指出这一点。然后,我们使用此代理子代替直接传递参考Callback子。

不同的是,.net框架现在知道,有一些指向该子所以不会垃圾回收它(清楚它从内存)

的MarshallAs位是有点多余的,因为这是默认编组,但它仅仅意味着我们明确地告诉.Net我们使用代理来访问非托管代码(在.Net框架之外的某些东西)

只是为了记录,我仍然不得不下载代码,因为它是实际上在Form1.vb是有关的位 - 但谢谢你尝试:)

+0

我的解释已掩盖了几位,但您可以从我发布在问题 – Basic 2010-08-24 00:44:42

+0

的评论中发布的链接获取更多信息。将运行一系列测试并让您知道结果。 – Cyclone 2010-08-24 00:45:30

+0

工作,非常感谢! – Cyclone 2010-08-24 00:51:52