0

For some reason SendInput() Pinvoke don't work. SendInput() always give 0 back, i tried to run it as Administrator, still no changes. it works perfectly in c++. i've been looking for hours, please help me. I'm running a Windows 8 64x bit computer. Maybe it has something to do with my operating system?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication6
{
    class Program
    {
        [DllImport("User32.dll", SetLastError = true)]
        public static extern int SendInput(int nInputs, INPUT[] inputs, int cbSize);

        public struct INPUT
        {
            public int type;
            public KEYBDINPUT ki;

        }

        private static KEYBDINPUT createKeybdInput(ushort wVK, uint flag)
        {
            KEYBDINPUT i = new KEYBDINPUT();

            i.wVk = wVK;
            i.wScan = 0;
            i.time = 0;
            i.dwExtraInfo = IntPtr.Zero;
            i.dwFlags = flag;
            return i;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct KEYBDINPUT
        {
            public ushort wVk;
            public ushort wScan;
            public uint dwFlags;
            public uint time;
            public IntPtr dwExtraInfo;
        }



        public static void sim_type()
        {

            INPUT[] inp = new INPUT[2];


            inp[0].type = 1;
            inp[0].ki = createKeybdInput(0x41, 0x0001);
            inp[1].type = 1;
            inp[1].ki = createKeybdInput(0x41, 0x0002);



            if (SendInput(2, inp, Marshal.SizeOf(typeof(INPUT))) == 0)
            {
                Console.WriteLine("error");
            }



        }

        static void Main(string[] args)
        {
            Console.ReadLine();
            sim_type();
            Console.ReadLine();

        }


    }
}

Thank you!

alcedo707
  • 11
  • 1
  • 5
  • Use Marshal.GetLastWin32Error() for proper error reporting. Some odds that you'll then also discover that your INPUT declaration is quite wrong. You cannot just leave stuff out you don't use. Use pinvoke.net for better declarations. Using KEYEVENTF_EXTENDEDKEY is wrong too. – Hans Passant Nov 14 '13 at 18:45

1 Answers1

0

The problem is that your translation of INPUT is incorrect. Look at the definition from MSDN:

typedef struct tagINPUT {
  DWORD type;
  union {
    MOUSEINPUT    mi;
    KEYBDINPUT    ki;
    HARDWAREINPUT hi;
  } DUMMYUNIONNAME;
} INPUT, *PINPUT, *LPINPUT;

Your definition of KEYBDINPUT is fine, but what about MOUSEINPUT and HARDWAREINPUT? You've just ignored them. This is a union so all three members are layed on top of each other. So your declaration can only work if KEYBDINPUT is the largest of the three. And smart money says it is not.

So, declare MOUSEINPUT and HARDWAREINPUT and include them in your translation of INPUT. You can get ready-made translations that work from pinvoke.net. And do make sure that you take notice of the error messages that are returned by the API call. You specified SetLastError to be true. So read the value out and take heed of it.

Pang
  • 9,564
  • 146
  • 81
  • 122
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490