[C#]Hak na klawiaturę

0

cześć.
Potrzebuję utworzyć hak na klawiaturę w c#, trochę o tym poczytałem na CodeGuru i msdnie i wziąłem się do roboty. Stworzyłem jakiś tam kod, który kompiluje się, jest zgodny z tym co wyczytałem (znaczy większa częśc jest odtwórczo przepisana, jak to często bywa przy nauce nowych rzeczy). Problem pojawia się po uruchomieniu programu. Hak nijak nie działa, nie jest wywoływany ani nic. Instaluję haka, deinstaluję na końcu, pomiędzy chcę czytać klawisze i dla testu wyświetlić wciśnięty klawisz w msgboxie, ale event naciśnięcia klawisza nigdy nie jest wywoływany.
Tutaj troche kodu:
Klasy hooka

abstract class Hook
{
//enum z winuser.h zawierajacy mozliwe typy hakow
public enum HookType
{
WH_MIN = (-1),
WH_MSGFILTER = (-1),
WH_JOURNALRECORD = 0,
WH_JOURNALPLAYBACK = 1,
WH_KEYBOARD = 2,
WH_GETMESSAGE = 3,
WH_CALLWNDPROC = 4,
WH_CBT = 5,
WH_SYSMSGFILTER = 6,
WH_MOUSE = 7,
WH_HARDWARE = 8,
WH_DEBUG = 9,
WH_SHELL = 10,
WH_FOREGROUNDIDLE = 11,
WH_CALLWNDPROCRET = 12,
WH_KEYBOARD_LL = 13,
WH_MOUSE_LL = 14
}

    private HookType hookType;

    //delegat funkcji wykonywanej po hooku
    protected delegate int HookProc(int code, IntPtr wParam, IntPtr lParam);

    protected HookProc hookProcedure;

    protected IntPtr hndHook;

    //do instalacji haka
    [DllImport("user32.dll")]
    protected static extern IntPtr SetWindowsHookEx(HookType hookType,
        HookProc proc, IntPtr hMod, int threadId);

    //do deinstalacji haka
    [DllImport("user32.dll")]
    protected static extern bool UnhookWindowsHookEx(IntPtr hHook);

    //do wywołania następnego haka
    [DllImport("user32.dll")]
    protected static extern int CallNextHookEx(IntPtr hHook, int code,
        IntPtr wParam, IntPtr lParam);


    //funkcja, ktora musi byc zrealizowana przez klase pochodna
    protected abstract int HookProcedure(int code, IntPtr wParam, IntPtr lParam);

    //konstruktor
    public Hook(HookType hookType)
    {
        this.hookType = hookType;
        hookProcedure = new HookProc(HookProcedure);
    }

    //instalacja haka
    public void Install()
    {
        hndHook = SetWindowsHookEx(hookType, hookProcedure,
            Marshal.GetHINSTANCE(this.GetType().Module), 0);
    }

    //odlaczenie haka
    public void Uninstal()
    {
        UnhookWindowsHookEx(hndHook);
    }
}

class KeyboardHook : Hook
{
    private int WM_KEYDOWN = 0x0100;

    public delegate void KeyboardEvent(Keys key);
    public event KeyboardEvent KeyDown;

    //konsturktor
    public KeyboardHook()
        : base(Hook.HookType.WH_KEYBOARD_LL)
    {
    }

    protected override int HookProcedure(int code, IntPtr wParam, IntPtr lParam)
    {
        if (code < 0)
            //uruchomienie nastepnego haka z kolejki
            return CallNextHookEx(hndHook, code, wParam, lParam);
        
        //code >= 0

        if (wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);
            KeyDown((Keys)vkCode);
        }

        CallNextHookEx(hndHook, code, wParam, lParam);

        return 0;
    }
}
<code class="c#">
//instalacja w evencie Load formy
            hak = new KeyboardHook();
            hak.Install();
            hak.KeyDown += new KeyboardHook.KeyboardEvent(msg);

//funcka msg, mało skomplikowana
private void msg(Keys key)
        {
            MessageBox.Show(key.ToString());
        }


//deinstalacja w evencie Closing
            hak.Uninstal();

Ktoś mnie wspomoże, czemu tak się dzieje?

0

hym, moze ktos sie ze mna nie zgodzic, ale jakos mi sie nie widzi wykorzystywanie .NET do tego celu...

Lepiej juz napisac natywna dll-ke w C, w .NET importowac tylko funkcje instsalacji i deinstalcji hooka.

Poza tym, widze ze probujesz zalozyc hook globalny, a skoro tak to ma prawo nie dzialac, bo obsluga hooka musi byc w oddzielnej (natywnej) bibliotece dll....

0

w takim razie ten art co go czytałem nie jest tak dobry, jak mi się wydawało, albo ja nie zauważam istotnych rzeczy.

Znaczy że haki w .NET są raczej niezbyt, to ok, ale podobno klawiaturę i myszę można hookować, a w sumie tylko to mi jest potrzebne, więc postanowiłem sprobować. Nijak natomiast nie wiedziałem, że hak powinien leżeć w dllce, żeby działać. Cóz, to się dowiedziałem przynajmniej ;)

To przyjrzę się jeszcze dokładniej tym hookom i wezmę się za to w C, może się uda :)
Dzięki za odpowiedź.

0

Hak jest LL (low level) więc nie musi być w osobnej dll'ce.
Sprawdziłeś co zwraca SetWindowsHookEx ?
Sprzwdziłeś czy w ogóle HookProcedure jest wywoływane ?
Poza tym wydaje mi się, że HookProcedure nie może być virtualna i chyba musi być nawet statyczna.

PS. haki LL strasznie zamulają kompa, bo każdy klawisz zanim trafi do aplikacji musi przejść przez twój hak.

0

Hmm, sprawdziłem i faktycznie, SetWindowsHookEx zwraca nulla, a co za tym idzie HookProcedure nigdy nie jest wywoływana.

Co do zamulania kompa, to jestem świadom, tak na razie tylko robię, żęby się z hakami zapoznać, popróbować, bo w praktyce człowiek się jednak najwięcej uczy, później będę szukał jakiegoś w miarę normalnego rozwiazania (czyli jak założyć globalny skrót klawiaturowy).

0
pako1337 napisał(a)

(czyli jak założyć globalny skrót klawiaturowy).
http://bloggablea.wordpress.com/2007/05/01/global-hotkeys-with-net/

1 użytkowników online, w tym zalogowanych: 0, gości: 1