Не удается захватить ввод пользователя из старой игры. Использование user32.dll

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

Эта концепция отлично работает в Windows, Chrome и более новых играх, даже таких, как Overwatch или Rocket League (даже если меня это не волнует). Проблема в том, что я пытаюсь захватить входные данные Call of Duty Modern Warfare (2007) и воспроизвести их, но ни захват входных данных, ни их воспроизведение не работают. Единственное, что работает, это CAPTURE движения мыши.

Я использую user32.dll для захвата и воспроизведения. Я попробовал несколько способов имитации ввода с клавиатуры, и все они работали везде, кроме этой конкретной игры.

keybd_event((byte)Key, 0, KEYEVENTF_KEYDOWN, UIntPtr.Zero);
//or
SendInput((uint)inputs.Length, inputs, Marshal.SizeOf(typeof(Input)));

Попытка имитировать ввод с клавиатуры. Я попробовал SendInput из user32.dll, потому что я читал, что игры DirectX обрабатывают ввод по-разному, но это тоже не сработало. Реализация входных данных для SendInput исходит из этого вопроса stackoverflow

Что касается чтения клавиатуры, я обычно использовал GetAsyncKeyState для чтения клавиатуры.

[DllImport("user32.dll")]
static extern short GetAsyncKeyState(Keys vKey);
//....
GetAsyncKeyState(key)

GetAsyncKeyState постоянно равен 0, независимо от реальной ситуации.

Я также пробовал хуки Windows для захвата клавиатуры безрезультатно.

    private static ListBox lb1;
    public Form1()
    {
        InitializeComponent();

        lb1 = listBox1;
        InstallHook();
    }

    private const int WH_KEYBOARD_LL = 13;
    // The callback function that will be called by the hook
    public delegate int KeyboardHookProc(int code, int wParam, ref KeyboardHookStruct lParam);

    public struct KeyboardHookStruct
    {
        public int vkCode;
        public int scanCode;
        public int flags;
        public int time;
        public int dwExtraInfo;
    }

    // Import the SetWindowsHookEx function from the Windows API
    [DllImport("user32.dll", SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookProc lpfn, IntPtr hMod, uint dwThreadId);

    // Import the UnhookWindowsHookEx function from the Windows API
    [DllImport("user32.dll", SetLastError = true)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

    // Import the CallNextHookEx function from the Windows API
    [DllImport("user32.dll", SetLastError = true)]
    private static extern int CallNextHookEx(IntPtr hhk, int nCode, int wParam, ref KeyboardHookStruct lParam);

    // The hook handle
    private static IntPtr hookHandle = IntPtr.Zero;

    // The hook procedure
    private static KeyboardHookProc hookProc = hookProcFunc;

    // Install the hook
    public static void InstallHook()
    {
        hookHandle = SetWindowsHookEx(WH_KEYBOARD_LL, hookProc, IntPtr.Zero, 0);
    }

    // Uninstall the hook
    public static void UninstallHook()
    {
        UnhookWindowsHookEx(hookHandle);
    }

    // The hook function
    private static int hookProcFunc(int code, int wParam, ref KeyboardHookStruct lParam)
    {
        if (code >= 0)
        {
            // Handle the keystroke here
            lb1.Items.Add("Keystroke: " + lParam.vkCode);
        }

        // Pass the keystroke on to the next hook in the chain
        return CallNextHookEx(hookHandle, code, wParam, ref lParam);
    }

mouse_event(MOUSEEVENTF_MOVE, movementX, movementY, 0, UIntPtr.Zero);

mouse_event также не имеет никакого эффекта.

Единственная часть, которая работает в этой конкретной игре, это:

[DllImport("user32.dll")]
static extern bool GetCursorPos(out Point lpPoint);

Стоит отметить, что в этой игре работают макросы AHK (AutoHotkey) и Logitech HUB. Также тот факт, что эта игра единственная, которую я заметил, где не работают ни захват, ни поднятие событий клавиатуры.

Мне понадобятся некоторые идеи, если проблема заключается в моем подходе к чтению и срабатыванию ввода с клавиатуры (и мыши) или если я неправильно понимаю, как использовать ранее упомянутые функции? Могу ли я добиться "универсального" макроса с помощью user32.dll, который будет работать с любым приложением без странностей? Если он не способен, то какие есть лучшие альтернативы, которые будут работать почти в любом случае, даже если это невозможно в С#, но, скажем, в C?

Вы запускаете Call of Duty Modern Warfare с правами администратора?

NineBerry 31.12.2022 04:18

Да, я не могу запустить без прав администратора. Вы предполагаете, что моя проблема связана с привилегиями?

adam sranko 31.12.2022 04:41

@NineBerry Я вручную запустил встроенный код с правами администратора, и это сработало..... ну, это интересное решение. Честно говоря, ваш вопрос как бы ответил на мой вопрос, но если бы я получил объяснение, что произошло сзади, это было бы здорово.

adam sranko 31.12.2022 04:46
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
3
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Windows по очевидным соображениям безопасности по умолчанию блокирует большую часть связи (сообщения Windows, доступ к дескрипторам друг друга, входные сигналы и т. д.) между процессами с повышенными и неповышенными правами.

С точки зрения процесса без повышенных прав процесс с повышенными правами выполняется как в другом сеансе Windows.

Чтобы иметь возможность взаимодействовать с процессом с повышенными правами из вашего собственного процесса, ваш собственный процесс также должен работать с повышенными правами (с правами администратора). Это включает в себя чтение и моделирование входных событий, происходящих в контексте процесса с повышенными правами.

Другие вопросы по теме