2010-08-23 123 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