简体   繁体   中英

SendInput() PInvoke doesn't work, i don't know why

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM