SendInput just doesn't work.

S

Sin Jeong-hun

Hi. I need to simulate keyboard and mouse events. For the first step,
I tried to move mouse using SendInput. But it didn't work. I searched
all over the internet for an example, but only questions were there.

Please give me what was wrong in the following code. I simplified the
code so that you can just copy it to a console app project, and run
it. Thank you for any help.

PS: I need to work with SendInput the way it is, not SendMessage or
modified INPUT structure, because there are a lot of other things to
do with SendInput.
Thank you.

--------Code (Program.cs)-------------
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

class Program
{
static void Main(string[] args)
{
MOUSEINPUT m = new MOUSEINPUT();
m.dx = 0;
m.dy = 0;
m.mouseData = 0;
m.time = 0;
m.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;

INPUT i = new INPUT();
i.type = INPUT_MOUSE;
i.mi = m;

INPUT[] inputs = new INPUT[] { i };
int isize = Marshal.SizeOf(i);
SendInput(1, inputs, isize);
}
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int
cbSize);
[StructLayout(LayoutKind.Explicit)]
struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
ushort wVk;
ushort wScan;
uint dwFlags;
uint time;
IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
uint uMsg;
ushort wParamL;
ushort wParamH;
}
const uint MOUSEEVENTF_MOVE = 0x0001;
const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
const uint MOUSEEVENTF_LEFTUP = 0x0004;
const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
const uint MOUSEEVENTF_RIGHTUP = 0x0010;
const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
const uint MOUSEEVENTF_XDOWN = 0x0080;
const uint MOUSEEVENTF_XUP = 0x0100;
const uint MOUSEEVENTF_WHEEL = 0x0800;
const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
const int INPUT_MOUSE = 0;
const int INPUT_KEYBOARD = 1;
const int INPUT_HARDWARE = 2;
}
 
S

Sin Jeong-hun

While wating for a reply from kind people, I tried myself that code in
native C++ code.

#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
MOUSEINPUT mi;
mi.dx=0;
mi.dy=0;
mi.dwExtraInfo=0;
mi.dwFlags=MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE;
mi.mouseData=0;
INPUT pInputs[1];
pInputs[0].mi=mi;
pInputs[0].type = INPUT_MOUSE;
SendInput(1,pInputs,sizeof(INPUT));
return 0;
}
It just worked fine. Why the C# code below doesn't work?
Please give me a hint. Thank you very much.


Hi. I need to simulate keyboard and mouse events. For the first step,
I tried to move mouse using SendInput. But it didn't work. I searched
all over the internet for an example, but only questions were there.

Please give me what was wrong in the following code. I simplified the
code so that you can just copy it to a console app project, and run
it. Thank you for any help.

PS: I need to work with SendInput the way it is, not SendMessage or
modified INPUT structure, because there are a lot of other things to
do with SendInput.
Thank you.

--------Code (Program.cs)-------------
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;

class Program
{
static void Main(string[] args)
{
MOUSEINPUT m = new MOUSEINPUT();
m.dx = 0;
m.dy = 0;
m.mouseData = 0;
m.time = 0;
m.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;

INPUT i = new INPUT();
i.type = INPUT_MOUSE;
i.mi = m;

INPUT[] inputs = new INPUT[] { i };
int isize = Marshal.SizeOf(i);
SendInput(1, inputs, isize);
}
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int
cbSize);
[StructLayout(LayoutKind.Explicit)]
struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
ushort wVk;
ushort wScan;
uint dwFlags;
uint time;
IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
uint uMsg;
ushort wParamL;
ushort wParamH;
}
const uint MOUSEEVENTF_MOVE = 0x0001;
const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
const uint MOUSEEVENTF_LEFTUP = 0x0004;
const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
const uint MOUSEEVENTF_RIGHTUP = 0x0010;
const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
const uint MOUSEEVENTF_XDOWN = 0x0080;
const uint MOUSEEVENTF_XUP = 0x0100;
const uint MOUSEEVENTF_WHEEL = 0x0800;
const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
const int INPUT_MOUSE = 0;
const int INPUT_KEYBOARD = 1;
const int INPUT_HARDWARE = 2;

}
 
S

Sin Jeong-hun

I have found out the reason. My Windows is 64bit version and the .NET
app becomes 64bit application. I changed the build option to x86, and
it worked.

Still don't know why the same API call fails if the .NET app is 64bit.
Do you know why?


While wating for a reply from kind people, I tried myself that code in
native C++ code.

#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
MOUSEINPUT mi;
mi.dx=0;
mi.dy=0;
mi.dwExtraInfo=0;
mi.dwFlags=MOUSEEVENTF_ABSOLUTE|MOUSEEVENTF_MOVE;
mi.mouseData=0;
INPUT pInputs[1];
pInputs[0].mi=mi;
pInputs[0].type = INPUT_MOUSE;
SendInput(1,pInputs,sizeof(INPUT));
return 0;}

It just worked fine. Why the C# code below doesn't work?
Please give me a hint. Thank you very much.

Hi. I need to simulate keyboard and mouse events. For the first step,
I tried to move mouse using SendInput. But it didn't work. I searched
all over the internet for an example, but only questions were there.
Please give me what was wrong in the following code. I simplified the
code so that you can just copy it to a console app project, and run
it. Thank you for any help.
PS: I need to work with SendInput the way it is, not SendMessage or
modified INPUT structure, because there are a lot of other things to
do with SendInput.
Thank you.
--------Code (Program.cs)-------------
using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
class Program
{
static void Main(string[] args)
{
MOUSEINPUT m = new MOUSEINPUT();
m.dx = 0;
m.dy = 0;
m.mouseData = 0;
m.time = 0;
m.dwFlags = MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE;
INPUT i = new INPUT();
i.type = INPUT_MOUSE;
i.mi = m;
INPUT[] inputs = new INPUT[] { i };
int isize = Marshal.SizeOf(i);
SendInput(1, inputs, isize);
}
[DllImport("user32.dll", SetLastError = true)]
static extern uint SendInput(uint nInputs, INPUT[] pInputs, int
cbSize);
[StructLayout(LayoutKind.Explicit)]
struct INPUT
{
[FieldOffset(0)]
public int type;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public uint mouseData;
public uint dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
ushort wVk;
ushort wScan;
uint dwFlags;
uint time;
IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
uint uMsg;
ushort wParamL;
ushort wParamH;
}
const uint MOUSEEVENTF_MOVE = 0x0001;
const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
const uint MOUSEEVENTF_LEFTUP = 0x0004;
const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
const uint MOUSEEVENTF_RIGHTUP = 0x0010;
const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
const uint MOUSEEVENTF_XDOWN = 0x0080;
const uint MOUSEEVENTF_XUP = 0x0100;
const uint MOUSEEVENTF_WHEEL = 0x0800;
const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
const int INPUT_MOUSE = 0;
const int INPUT_KEYBOARD = 1;
const int INPUT_HARDWARE = 2;
 
M

Mattias Sjögren

Still don't know why the same API call fails if the .NET app is 64bit.
Do you know why?

I believe all the FieldOffset(4) must be FieldOffset(8) when running
as a 64-bit app.

Since you're only using the MOUSEINPUT part of the union, and it
happens to be the biggest one of the three, you can remove the other
two and change the declaration of INPUT to

struct INPUT
{
public int type;
public MOUSEINPUT mi;
}

That should hopefully make the code work on both 32-bit and 64-bit.



Mattias
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top