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

+0

Я думаю, что требуется дополнительная информация. * (IE: code) * – ChaosPandion

+0

Посмотрите на изменения, у меня была ссылка HTML, но я думаю, что ссылки html больше не разрешены. Теперь я использую уценку для ссылки. – Cyclone

ответ

3

Посмотрите на код в Form1.vb, где он делает это:

StartLog(nhWnd_text, AddressOf CallBack) 

Вот где он говорит, возьмите местоположение функции обратного вызова и используйте его для получения сообщений, которые я получаю относительно события клавиатуры s.

попробовать что-то вроде этого:

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 немного лишнего, как это по умолчанию marshalling, но это просто означает, что мы явно говорим .Net, что мы используем делегат для доступа к неуправляемому коду (что-то вне рамки .Net)

Только для записи мне все равно пришлось загрузить код, поскольку он был на самом деле бит в Form1.vb, который был уместным - Но спасибо за попытку :)

+0

Мое объяснение прояснилось по нескольким битам, но вы можете получить дополнительную информацию по ссылке, которую я разместил в комментариях по вопросу – Basic

+0

Работаю до сих пор. Пройдет серию тестов и сообщит вам о результатах. – Cyclone

+0

Это сработало, спасибо огромное! – Cyclone

Смежные вопросы