8

I can send any windows application key strokes with PostMessage api. But I can't send key strokes to Game window by using PostMessage.

Anyone know anything about using Direct Input functions for sending keys to games from C#.

Munim Munna
  • 17,178
  • 6
  • 29
  • 58
İbrahim Akgün
  • 1,527
  • 11
  • 37
  • 63
  • Isn't this a duplicate of http://stackoverflow.com/questions/407020/about-my-macro-programs ? If not, why did you create a new account? – M4N Jan 03 '09 at 21:36
  • 1
    no it is not duplicate . I have not create a new account.Account name is still same.And i wanna send keys to games.Not to windows applications. – İbrahim Akgün Jan 03 '09 at 21:47
  • maybee I'm missing soemthign but aren't games Window Applications? Don't games have message loop they are pumping the user's input through to handle? – JoshBerke Jan 03 '09 at 21:54
  • or maybe the game is built to resist this sort of thing – Andrew Cox Jan 03 '09 at 21:56
  • +1 for close as exact duplicate – UnkwnTech Jan 03 '09 at 21:56
  • @Andrew I could see that, which in this case this question is preety vague. – JoshBerke Jan 03 '09 at 22:03
  • yes Games are windows applications too.But I cant send keystrokes to my game with PostMessage api and keybd_event api.Where is the problem.Is this any other alternative method for Sending Keys to games ? I am lookin everywhere for solution almost 1 week. – İbrahim Akgün Jan 03 '09 at 22:15
  • 1
    Don't close it - he specifically asks for DirectInput, not generic win32 programs. – Nils Pipenbrinck Jan 04 '09 at 00:13
  • 1
    Possible duplicate of [Simulating Key Press c#](https://stackoverflow.com/questions/3047375/simulating-key-press-c-sharp) – Deniz Jun 15 '18 at 09:25
  • *"I can send any windows application key strokes with `PostMessage` api."* - Er, no, [you can't simulate keyboard input with PostMessage](https://devblogs.microsoft.com/oldnewthing/20050530-11/?p=35513). – IInspectable Jun 04 '20 at 09:58

5 Answers5

8

One alternative, instead of hooking into DirectX, is to use a keyboard driver (this is not SendInput()) to simulate key presses - and event mouse presses.

You can use Oblita's Interception keyboard driver (for Windows 2000 - Windows 7) and the C# library Interception (wraps the keyboard driver to be used in C#).

With it, you can do cool stuff like:

input.MoveMouseTo(5, 5);
input.MoveMouseBy(25, 25);
input.SendLeftClick();

input.KeyDelay = 1; // See below for explanation; not necessary in non-game apps
input.SendKeys(Keys.Enter);  // Presses the ENTER key down and then up (this constitutes a key press)

// Or you can do the same thing above using these two lines of code
input.SendKeys(Keys.Enter, KeyState.Down);
Thread.Sleep(1); // For use in games, be sure to sleep the thread so the game can capture all events. A lagging game cannot process input quickly, and you so you may have to adjust this to as much as 40 millisecond delay. Outside of a game, a delay of even 0 milliseconds can work (instant key presses).
input.SendKeys(Keys.Enter, KeyState.Up);

input.SendText("hello, I am typing!");

/* All these following characters / numbers / symbols work */
input.SendText("abcdefghijklmnopqrstuvwxyz");
input.SendText("1234567890");
input.SendText("!@#$%^&*()");
input.SendText("[]\\;',./");
input.SendText("{}|:\"<>?");

Because the mechanism behind these key presses is a keyboard driver, it's pretty much unrestricted.

Jason
  • 6,878
  • 5
  • 41
  • 55
7

An alternate way would be to hook the DirectInput API directly - Microsoft Research has provided a library to do this already: http://research.microsoft.com/en-us/projects/detours/

Once you hook into the API, you can do whatever you want with it. However, it's worth noting that in recent versions of Windows, DirectInput for mouse & keyboard input is just a wrapper around the Win32 windows messages. DirectInput spawns a thread in the background and simply intercepts window messages before passing them along back to the application. It's one of the reasons why Microsoft no longer recommends the use of DirectInput - and it means that messaging APIs like PostMessage should work just fine.

Adrian
  • 396
  • 1
  • 4
1

There is now way to do this via the DirectInput API.

The only way to archive the same effect would be to write your own DirectInput COM object which just wraps the normal DirectInput object. Afterwards you can add code to simulate keystrokes. The trick is to replace the Win32 dinput.dll with your version. All games will then load your DLL on startup.

I'm afraid that you can't do that from a managed language though. You have to do this with native code as it requirs quite a bit of low level hackery.

Nils Pipenbrinck
  • 83,631
  • 31
  • 151
  • 221
0

Worked for a friends Game (Nostale) without probems:

Also here a usefull list of Virtual Key Codes

        [DllImport("user32.dll")]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        [DllImport("user32.dll")]
        static extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

        private void button1_Click(object sender, EventArgs e)
        {
            const int WM_SYSKEYDOWN = 0x0104;
            const int VK_SPACE = 0x20;

            IntPtr WindowToFind = FindWindow(null, "WINDOW NAME");

            PostMessage(WindowToFind, WM_SYSKEYDOWN, VK_SPACE, 0);
        }
Deniz
  • 429
  • 1
  • 4
  • 19
  • it won't work. Your example is just what author tried, but in another way. – Kamil Nov 25 '19 at 18:36
  • 1
    I don't think you understood the problem. Your friend's game doesn't have any defense against bots, and doesn't filter input. The game the author tried to automate DID, sending input like that will FAIL in that game, since windows shouts as loudly as possible that the input sent is fake, and games can detect it. – Parasol Kirby Oct 31 '21 at 16:48
  • @ParasolKirby Ah okay I get what u mean. You know a solution for that? What I heard for protections like that is a own driver which simulates a real keyboard. – Deniz Nov 11 '21 at 08:40
  • @ParasolKirby Jason's solution works at games with defense against bots ? – Deniz Nov 11 '21 at 08:53
  • 1
    @Deniz you actually don't need all that, you can just remove the little tag windows attaches to the input. Also I have not yet figured out if Jason's solution works with games that filter input. – Parasol Kirby Nov 12 '21 at 11:31
  • @ParasolKirby Remove which tag? Do u have an little example ? I'am just curious. – Deniz Nov 16 '21 at 13:12
0

You can use the unmanaged SendInput function for this. It posts the input on a level lower then DirectInput. It is very important to know what keycodes to send. These can vary between games. If Windows Virtual keycodes don't work for a game, you can try sending DIKEYBOARD constants (like DIKEYBOARD_A etc.) and if it still doesn't work keep trying. Half Life or Counter Strike, for instance, expect ASCII codes as keycodes (it took me a while to figure this out)

Radu Simionescu
  • 4,518
  • 1
  • 35
  • 34