Код user32.dll работает под x86, но не под x64 - PullRequest
0 голосов
/ 31 октября 2018

Я использовал какой-то код из https://github.com/cerebrate/mousejiggler, чтобы компьютер Windows не работал. Это сработало найти, но когда я перенес его в новое приложение, оно начинало падать, когда оно выполнялось. Конкретно на линии:

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

Новое приложение работало как приложение x64, где старое было x86. Построение нового приложения для x86 решило эту проблему. Полный код ниже. Я изо всех сил пытаюсь понять, почему это так. В стойке есть один IntPtr, который изменится с 4 до 8 байтов в зависимости от платформы, но, насколько я знаю, способа изменить это не существует. Я думаю, я мог бы создать 32-битный int-указатель и использовать небезопасный код, но я даже не уверен, что это на самом деле проблема.

Есть идеи, как это исправить для платформ x64?

[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;
}

1 Ответ

0 голосов
/ 31 октября 2018

Он не будет работать, так как функции Windows зависят от архитектуры, в данном случае 32-разрядные.

Чтобы заставить SendInput работать на 64-битных системах, см. SendInput и 64bit

.

Однако не существует эквивалентной 64-битной функции для GetLastInputInfo, но смотрите Существует ли 64-битный эквивалент GetLastInputInfo / LASTINPUTINFO? , как вы могли бы сделать это, если вам нужно запустить в 64 бит.

...