Member 7912784 Ответов: 2

Имитируйте эти ключи для неактивного приложения с помощью C#


Я пытаюсь использовать PostMasseg для отправки VK в неактивное приложение, которое я хочу отправить (пробел+1)

но он всегда посылает только (1)

вот какой шпион++ читаю скулю нажимаю (пробел+1)

<000001> 000702FC P WM_KEYDOWN nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000002> 000702FC P WM_CHAR chCharCode:'32' (32) cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000003> 000702FC P WM_KEYDOWN nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000004> 000702FC P WM_CHAR chCharCode:'49' (49) cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0<br />
<br />
<000005> 000702FC P WM_KEYUP nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:1 fUp:1<br />
<br />
<000006> 000702FC P WM_KEYUP nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:1 fUp:1<br />
<br />
<000007> 000702FC P WM_SYSKEYDOWN nVirtKey:VK_MENU cRepeat:1 ScanCode:38 fExtended:0 fAltDown:1 fRepeat:0 fUp:0


как это смоделировать?

теперь у меня есть кое что еще чего я не понимал я не получил того что мне нужно с этим кодом


public static void sendKey(IntPtr hwnd, Keys keyCode)
    {
        uint scanCode = MapVirtualKey((uint)keyCode, 0);
        uint lParam;
        // 
        //KEY DOWN
        lParam = (0x00000001 | (scanCode << 16));
        //if (extended)
        //{
        //    lParam |= 0x01000000;
        //}
        PostMessage(hwnd, (UInt32)WM_KEYDOWN, (IntPtr)keyCode, (IntPtr)lParam);
        Thread.Sleep(100);

        uint scanCode1 = MapVirtualKey((uint)Keys.D1, 0);
        uint lParam1;
        // 
        //KEY DOWN
        lParam1 = (0x00000001 | (scanCode1 << 16));

        PostMessage(hwnd, (UInt32)WM_KEYDOWN, (IntPtr)Keys.D1, (IntPtr)lParam1);

        Thread.Sleep(50);
        //KEY UP
        //lParam |= 0xC0000000;  // set previous key and transition states (bits 30 and 31)
        PostMessage(hwnd, WM_KEYUP, (IntPtr)Keys.D1, (IntPtr)(0xC0020001));
        PostMessage(hwnd, WM_KEYUP, (IntPtr)keyCode, (IntPtr)(0xC0390001));

    }


и spy++ считывает это из моего приложения, когда я нажимаю командную кнопку

<000001> 000401BA P WM_KEYDOWN nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000002> 000401BA P WM_CHAR chCharCode:'32' (32) cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000003> 000401BA P WM_KEYDOWN nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000004> 000401BA P WM_CHAR chCharCode:'49' (49) cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:0 fUp:0

<000005> 000401BA P WM_KEYUP nVirtKey:'1' cRepeat:1 ScanCode:02 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

<000006> 000401BA P WM_KEYUP nVirtKey:VK_SPACE cRepeat:1 ScanCode:39 fExtended:0 fAltDown:0 fRepeat:1 fUp:1

но он не сделал того, что мне нужно ?

может ли кто-нибудь сказать мне, где ошибка

я делаю это с помощью этого кода

<pre>using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {

        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern uint MapVirtualKey(uint uCode, uint uMapType);

        [DllImport("user32.dll", SetLastError = true)]
        static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

        const uint WM_KEYDOWN = 0x0100;
        const uint WM_KEYUP = 0x0101;
        const int WM_SYSKEYDOWN = 0x0104;
        const int KEYEVENTF_EXTENDEDKEY = 0x0001; //Key down flag
        const int KEYEVENTF_KEYUP = 0x0002; //Key up flag

        public Form1()
        {
            InitializeComponent();
            LoadProcess();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Process p = (Process)comboBox1.SelectedItem;
            keybd_event((byte)Keys.Space, (byte)0x02, (int)WM_KEYDOWN, 0);
            sendKeyUp(p.MainWindowHandle, Keys.D1);
            sendKeyDown(p.MainWindowHandle, Keys.D1);
            keybd_event((byte)Keys.Space, (byte)0x82, KEYEVENTF_KEYUP, 0);
        }

        private void LoadProcess()
        {
            comboBox1.Items.Clear();
            comboBox1.DisplayMember = "MainWindowTitle";
            foreach (Process item in Process.GetProcesses())
            {
                try
                {
                    comboBox1.Items.Add(item);
                }
                catch { }
            }
        }

        public static void sendKeyDown(IntPtr hwnd, Keys keyCode)
        {
            uint scanCode = MapVirtualKey((uint)keyCode, 0);
            uint lParam;
            // 
            //KEY DOWN
            lParam = (0x00000001 | (scanCode << 16));
            //if (extended)
            //{
            //    lParam |= 0x01000000;
            //}
            PostMessage(hwnd, (UInt32)WM_SYSKEYDOWN, (IntPtr)keyCode, (IntPtr)lParam);
        }

        public static void sendKeyUp(IntPtr hwnd, Keys keyCode)
        {
            uint scanCode = MapVirtualKey((uint)keyCode, 0);
            uint lParam;
            // 
            //KEY DOWN
            lParam = (0xC0000001 | (scanCode << 16));
            //KEY UP
            //lParam |= 0xC0000001;  // set previous key and transition states (bits 30 and 31)
            PostMessage(hwnd, WM_KEYUP, (IntPtr)keyCode, (IntPtr)lParam);
        }
    }
}


но все же есть ошибка

приложение не остановило его продолжайте повторять нажатие клавиши

Что я уже пробовал:

const uint WM_KEYDOWN = 0x100;
const uint WM_KEYUP = 0x0101;

PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.D1, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.D1, (IntPtr)0x0);

2 Ответов

Рейтинг:
7

Member 7912784

я нахожу способ решить эту проблему

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;

namespace SendKeysWithModefire
{
   public class KeysTest
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);

        [DllImport("user32.dll")]
        public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        const uint WM_KEYDOWN = 0x100;
        const uint WM_KEYUP = 0x101;
        const uint Key_Down = 0x0001;
        const uint Key_Up = 0x0002;
        private volatile bool _shouldStop;
        private Process _sroProcess;
        private Keys _modefirKey;
        private Keys _pressKey;

        public KeysTest(Process targetSro,Keys modKey,Keys pressKey)
        {
            _sroProcess = targetSro;
            _modefirKey = modKey;
            _pressKey = pressKey;
        }

        public void SendKeys()
        {
            SendKeyWithModefir(_sroProcess, (byte)_modefirKey, (byte)_pressKey);
        }

        public void SendKeyWithModefir(Process _p, byte ModKey, byte PressKey)
        {
            while (!_shouldStop)
            {
                keybd_event(ModKey, 0, Key_Down, 0);
                Thread.Sleep(50);
                PostMessage(_p.MainWindowHandle, WM_KEYDOWN, (IntPtr)(PressKey), (IntPtr)(0));
                PostMessage(_p.MainWindowHandle, WM_KEYUP, (IntPtr)(PressKey), (IntPtr)(0));
                Thread.Sleep(50);
                keybd_event(ModKey, 0, Key_Up, 0);
            }
        }

        public void RequestStop()
        {
            _shouldStop = true;
        }

        ~KeysTest()
        {
            GC.Collect();
        }
    }
}


и это как раз то, что нужно

private KeysTest sendingKeys;
private Thread startSending;

...............

//that code send Left Control + 1
//s is the target process
sendingKeys = new KeysTest(s, Keys.LControlKey, Keys.D1);
startSending = new Thread(sendingKeys.SendKeys); 
startSending.Start();
while (!startSending.IsAlive) ;
Thread.Sleep(2000);
sendingKeys.RequestStop();
startSending.Join();
startSending.Abort();


Рейтинг:
0

Richard MacCutchan

Попробуйте отправить сообщение WM_KEYUP перед следующим WM_KEYDOWN:

PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.Space, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.D1, (IntPtr)0x0);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.D1, (IntPtr)0x0);


Member 7912784

я пытаюсь это сделать, но не получается, мне нужно нажать (пробел + 1)

Richard MacCutchan

Что значит "не работает" означает? Насколько я могу судить по вашему шпионскому следу++ , все ключи отправляются правильно.

Member 7912784

да, но это не произвело такого эффекта, как когда я нажимаю их вручную

Richard MacCutchan

Это могло бы помочь, если бы вы на самом деле объяснили, чего вы ожидаете от него и какой результат он дает.

Member 7912784

я пытаюсь создать ключ прижимной для игры

одна из команд игры-это (пробел + число)

я пытаюсь смоделировать это с помощью кода

но когда я это делаю, результат с кодом таков, как я нажимаю только число, а не как я нажимаю (пробел + число)

Richard MacCutchan

Вам нужно точно выяснить, как игровая программа обрабатывает клавиатуру. Это может быть не так, как вы думаете.

phil.o

Большинство игр в настоящее время имеют защиту от этого типа взлома; подумайте о ММО-играх, которые почти потеряли кредиты своего сообщества из-за слишком большого количества ботов (Guild Wars I, например).
Игра, которую вы пытаетесь взломать, может содержать такую защиту.

Member 7912784

я нахожу способ сделать это

const uint WM_KEYDOWN = 0x100;
const uint WM_KEYUP = 0x101;
const int KeyDown = 0x0001;
const int KeyUp = 0x0002;
const byte VK_SPACE = 0x20;
const byte SpaceSC = 39;



private void button1_Click(object sender, EventArgs e)
{
Process p = (Process)comboBox1.SelectedItem;
keybd_event(VK_SPACE, 0, Key_Down , 0);
Thread.Sleep(50);
PostMessage(p.MainWindowHandle, WM_KEYDOWN, (IntPtr)Keys.D1, IntPtr.Zero);
PostMessage(p.MainWindowHandle, WM_KEYUP, (IntPtr)Keys.D1, IntPtr.Zero);
keybd_event(VK_SPACE, 0, Key_Up, 0);
}


но код продолжает повторять нажатие клавиши без остановки

как это исправить