简体   繁体   中英

user32.dll code works under x86 but not x64

I have been using some code from https://github.com/cerebrate/mousejiggler to keep a Windows PC from going idle. It worked find, but when I ported it to a new app it started crashing when ever it executed. Specifically at the line:

if (SendInput(1, ref inp, 28) != 1)
    throw new Win32Exception();

The new app was running as a x64 application, where as the old one was x86. Building the new app for x86 fixed this issue. The full code is below. I am struggling to work out why this is the case. There is one IntPtr in the strut that will change from 4 bytes to 8 bytes depending on the platform, but as far as I'm aware there isn't a way to change this. I guess I could create a 32 bit int pointer and use unsafe code, but I'm not even sure this is actually the problem yet.

Any ideas on how I can fix it for x64 platforms?

[StructLayout(LayoutKind.Sequential)]
struct LASTINPUTINFO
{
    public static readonly int SizeOf = Marshal.SizeOf(typeof(LASTINPUTINFO));

    [MarshalAs(UnmanagedType.U4)]
    public UInt32 cbSize;
    [MarshalAs(UnmanagedType.U4)]
    public UInt32 dwTime;
}

[DllImport("user32.dll")]
static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

static uint GetLastInputTime()
{
    uint idleTime = 0;
    LASTINPUTINFO lastInputInfo = new LASTINPUTINFO();
    lastInputInfo.cbSize = (uint)Marshal.SizeOf(lastInputInfo);
    lastInputInfo.dwTime = 0;

    uint envTicks = (uint)Environment.TickCount;

    if (GetLastInputInfo(ref lastInputInfo))
    {
        uint lastInputTick = lastInputInfo.dwTime;

        idleTime = envTicks - lastInputTick;
    }

    return ((idleTime > 0) ? (idleTime / 1000) : 0);
}

public static class Jiggler
{
    internal const int INPUT_MOUSE = 0;
    internal const int MOUSEEVENTF_MOVE = 0x0001;

    [DllImport("user32.dll", SetLastError = true)]
    private static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize);

    public static void Jiggle(int dx, int dy)
    {
        var inp = new INPUT();
        inp.TYPE = Jiggler.INPUT_MOUSE;
        inp.dx = dx;
        inp.dy = dy;
        inp.mouseData = 0;
        inp.dwFlags = Jiggler.MOUSEEVENTF_MOVE;
        inp.time = 0;
        inp.dwExtraInfo = (IntPtr)0;

        if (SendInput(1, ref inp, 28) != 1)
            throw new Win32Exception();
    }
}

[StructLayout(LayoutKind.Sequential)]
internal struct INPUT
{
    public int TYPE;
    public IntPtr dwExtraInfo;
    public int dwFlags;
    public int dx;
    public int dy;
    public int mouseData;
    public int time;
}

Its not going to work as the Windows functions are architecture specific, in this case 32 bit specific.

To make SendInput work for 64bit see SendInput and 64bits

However there is not an equivalent 64 bit function for GetLastInputInfo but see Is there a 64 bit equivalent to GetLastInputInfo / LASTINPUTINFO? for how you might be able to do it if you need to be running in 64 bit.

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