Отправляет email-рассылки с помощью сервиса Sendsay

[prg] Клавиатурный хук на c#

Приветствую всех. Недавно начал осваивать c#. Раньше писал автоматизации
на autoit, но из-за багов и необщительного разработчика, пришлось
переезжать на c#.

Прикрутил dll autoitX себе, и всё бы хорошо, но добрался я до хуков
клавиатуры.

Нашёл код хука, разобрался, прикрутил к форме, и всё работает, и даже
при сворачивании формы. Но как реализовать Клавиатурный хук без формы?

Что я пытался делать:

Создал делегат.

public delegate void D_Window();

Создал событие на основе делегата.

public static event D_Window L_Window;

Создал метод в котором вызываю событие по условию.

public static void M_Window()
{
if (AutoItX.WinActive("[TITLE:Яндекс диск;CLASS:#32770]", "") == 1)
{
L_Window();
}
}

Связал событие с методом хука в точке входа.

AutoSoft.L_Window += AutoSoft.SetHook;

Вызвал метод M_Window в цикле, и клавиши не перехватываются. Если
связываю событие с любым другим методом не связанным с хуком, то всё
работает.

Пробовал добавлять Application.Run() без аргументов, цикл обработки
сообщений без формы запускается, но до моего метода в точке входа не
доходит. Код хука ниже, он точно рабочий, если его назначить на событие
загрузки формы, то всё перехватывается.

namespace AutoSoft
{
public partial class AutoSoft
{
[DllImport("kernel32.dll")]
private static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("user32.dll")]
private static extern IntPtr SetWindowsHookEx( int idHook,
LowLevelKeyboardProcDelegate lpfn, IntPtr hMod, int dwThreadId);
[DllImport("user32.dll")]
private static extern IntPtr CallNextHookEx(IntPtr idHook, int nCode,
int wParam, IntPtr lParam);
[DllImport("user32.dll")]
private static extern bool UnhookWindowsHookEx(IntPtr hInstance);
[StructLayout(LayoutKind.Sequential)]
private struct KeyboardHookStruct
{
public readonly int VirtualKeyCode;
public readonly int ScanCode;
public readonly int Flags;
public readonly int Time;
public readonly IntPtr ExtraInfo;
}
private static LowLevelKeyboardProcDelegate m_callback;
private static IntPtr m_hHook;
private delegate IntPtr LowLevelKeyboardProcDelegate(int nCode, IntPtr
wParam, IntPtr lParam);
public static void SetHook()
{
m_callback = LowLevelKeyboardHookProc;
var hInstance = LoadLibrary("User32");
m_hHook = SetWindowsHookEx(13, m_callback, hInstance, 0);
}
public static void UnHook()
{
UnhookWindowsHookEx(m_hHook);
}
public static IntPtr LowLevelKeyboardHookProc(int code, IntPtr wParam,
IntPtr lParam)
{
if (code == 0)
{
var khs = (KeyboardHookStruct) Marshal.PtrToStructure(lParam, typeof
(KeyboardHookStruct));
Debug.Print("Hook: Code: {0}, WParam: {1},{2},{3},{4} ", code, wParam,
lParam, khs.VirtualKeyCode, khs.ScanCode, khs.Flags, khs.Time);
Debug.Print(khs.VirtualKeyCode.ToString());
if (khs.VirtualKeyCode == 9 && wParam.ToInt32() == 260 && khs.ScanCode
== 15)
{
SoundPlay(@"Sounds\ok.wav");
return (IntPtr)1;
}
}
return CallNextHookEx(m_hHook, code, (int)wParam, lParam);
}
}
}

Привожу код точки входа.

using System;
using System.Threading;
using System.Runtime.InteropServices;
using Un4seen.Bass;
using AutoIt;
using System.Windows.Forms;
using System.Linq;
using System.Diagnostics;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Collections;
namespace AutoSoft
{
public partial class AutoSoft
{
static void Main(string[] args)
{
bool Instance;
Mutex MTX = new Mutex(true, "AutoSoftMTX", out Instance);
if (Instance==false)
{
MessageBox.Show(
"Внимание",
"Программа уже запущенна",
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.DefaultDesktopOnly);
return;
}
AutoItX.AutoItSetOption("WinTitleMatchMode", 2);
AutoSoft.L_Window += AutoSoft.SetHook;
while(true)
{
M_Window();
}
}
}
}

И код события с методом проверки условия.

namespace AutoSoft
{
public partial class AutoSoft
{
public delegate void D_Window();
public static event D_Window L_Window;
public static void M_Window()
{
if (AutoItX.WinActive("[TITLE:Яндекс диск;CLASS:#32770]", "") == 1)
{
L_Window();
}
}
}
}

Ещё где-то читал про метод GetMessage, но что-то не проникся как это
может помочь сделать хук без формы.

Помогите пожалуйста разобраться. Спасибо.

Ответить   Fri, 15 Nov 2019 12:47:50 +0300 (#3636803)