Я пытаюсь использовать скрипт powershell (используя C #) для прослушивания нажатий клавиш.Это работает за короткое время до выхода из строя.Что интересно, после того, как я добавил некоторые записи консоли, похоже, что ошибка происходит вне моего кода.
Вот сценарий powreshell:
Add-Type -TypeDefinition @"
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace KeyLogger {
public static class Program {
private const int WH_KEYBOARD_LL = 13;
private static IntPtr hookId = IntPtr.Zero;
public static void Begin() {
hookId = SetHook();
Application.Run();
UnhookWindowsHookEx(hookId);
}
private static IntPtr SetHook() {
IntPtr moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
return SetWindowsHookEx(WH_KEYBOARD_LL, HookCallback, moduleHandle, 0);
}
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
Console.WriteLine('0');
if (nCode == 0) {
Console.WriteLine('1');
Console.WriteLine(Marshal.ReadInt32(lParam) + " " + wParam + " ");
}
Console.WriteLine('2');
IntPtr x = CallNextHookEx(hookId, nCode, wParam, lParam);
Console.WriteLine('3');
return x;
}
private delegate IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll")]
private static extern IntPtr GetModuleHandle(string lpModuleName);
}
}
"@ -ReferencedAssemblies System.Windows.Forms
[KeyLogger.Program]::Begin();
Ошибка:
Произошла ошибка, которая не была должным образом обработана.Дополнительная информация показана ниже.Процесс Windows PowerShell завершится.Необработанное исключение: System.NullReferenceException: ссылка на объект не установлена для экземпляра объекта.
Обратите внимание на Console.WriteLine
в методе HookCallback
.Но последняя напечатанная строка отладки - 3
, указывая, что ошибка происходит за пределами HookCallback
.Что еще более интересно, если у меня запущено несколько экземпляров скрипта, они не все одновременно выдают ошибку;может произойти сбой, но остальные продолжат еще немного.
Я не слишком знаком с powershell или C #, поэтому мне интересно, как получить больше отладочной информации?Я ожидал бы номер строки или имя файла или библиотеки, где произошла ошибка, но я не уверен, как получить эту информацию.
Отказ от ответственности, я взял сценарий отсюда https://blogs.msdn.microsoft.com/toub/2006/05/03/low-level-keyboard-hook-in-c/ (слегка измененный).
Редактировать: я принял ответ Стюарда, так как он был очень полезным, но, как я сказал в комментариях, для работы потребовались небольшие модификации. Для удобства будущих читателей, вот модификации, которые сработали:
private static HookProc callback;
...
private static IntPtr SetHook() {
callback = HookCallback;
IntPtr moduleHandle = GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName);
return SetWindowsHookEx(WH_KEYBOARD_LL, callback, moduleHandle, 0);
}
...
Я сделал больше поиска и чтения на C #, и, кажется, причина была в том, что SetWindowsHookEx
не управляет и не поддерживает этот параметр делегата hookProc, а передача статического метода напрямую создает локальный (локальный для метода) делегат, который готов к удалению после возврата метода SetHook
.