Ключи SendInput на машинах Win32 и Win64 - PullRequest
1 голос
/ 04 января 2011

Я использовал sendInput () в xp 32bits, используя веб-сервисы, чтобы выдвинуть F5 из текущих сфокусированных окон. Сейчас под Vista win64 я не могу получить этот результат. Некоторые статьи указывают на проблемы с использованием 4 бит или 8 бит, но это не решает проблему в Vista с дифференциальной компиляцией и FieldOffset (4) или (8). Другие говорят, что больше нет взаимодействия между экраном Vista и окном с помощью этого метода SendInput (). Может кто-нибудь указать решение подтолкнуть F5 в машинах win32 и win64. Спасибо.

uint intReturn = 0;
NativeWIN32.INPUT structInput;
structInput = new NativeWIN32.INPUT();
structInput.type = (uint)1;
structInput.ki.wScan = 0;
structInput.ki.time = 0;
structInput.ki.dwFlags = 0;
structInput.ki.dwExtraInfo = IntPtr.Zero; 

// Key down the actual key-code 
structInput.ki.wVk = (ushort)NativeWIN32.VK.F5;
//vk; 
intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));
// Key up the actual key-code 
structInput.ki.dwFlags = NativeWIN32.KEYEVENTF_KEYUP;
structInput.ki.wVk = (ushort)NativeWIN32.VK.F5;
//vk; 
intReturn = NativeWIN32.SendInput((uint)1, ref structInput, Marshal.SizeOf(structInput));



public class NativeWIN32
{ 
    public const ushort KEYEVENTF_KEYUP = 0x0002; 
    public enum VK : ushort 
    {  
        F5                   = 0x74,  
    } 

    public struct KEYBDINPUT 
    {  
        public ushort wVk;  
        public ushort wScan;  
        public uint dwFlags;  
        public long time;  
        public uint dwExtraInfo; 
    }; 
    [StructLayout(LayoutKind.Explicit,Size=28)]  
    public struct INPUT 
    {  
        [FieldOffset(0)] 
        public uint type;
        #if x86 
    //32bit 
    [FieldOffset(4)] 
        #else
        //64bit 
        [FieldOffset(8)]
        #endif
        public KEYBDINPUT ki; 
    };

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

}

Ответы [ 2 ]

3 голосов
/ 30 апреля 2012

Я столкнулся с этой проблемой с 32/64 на XP, и это решение я придумал.Я не эксперт pInvoke, поэтому может быть более элегантное решение.

Основная причина, по-видимому, заключается в том, что размер слова в двух архитектурах различен.Это отбрасывает, когда некоторые сложные данные анализируются из структур данных, используемых во внешнем вызове.Я должен был объявить два отдельных набора структур и внешних вызовов для 64-битных и 32-битных.

internal static class SendInputExternalCalls
{
    // This SendInput call uses the 32bit input structure.
    [DllImport("user32.dll", SetLastError = true, EntryPoint = "SendInput")]
    public static extern UInt32 SendInput(
        UInt32 numInputs,
        [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)]
        SEND_INPUT_FOR_32_BIT[] sendInputsFor,
        Int32 cbSize);

    // This SendInput call uses the 64bit input structure.
    [DllImport("user32.dll", SetLastError = true, EntryPoint = "SendInput")]
    public static extern UInt32 SendInput(
        UInt32 numInputs,
        [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] 
        SEND_INPUT_FOR_64_BIT[] sendInputsFor,
        Int32 cbSize);
}

// This is the basic structure for 32 bit input.  SendInput allows for other input   
// types, but I was only concerned with keyboard input, so I harcoded my strucs that way.
[StructLayout(LayoutKind.Explicit, Pack = 1)]
internal struct SEND_INPUT_FOR_32_BIT
{
    [FieldOffset(0)]
    public uint InputType;  
    [FieldOffset(4)]
    public KEYBOARD_INPUT_FOR_32_BIT KeyboardInputStruct; 
}

// Here is the structure for keyboard input.  The key code, scan code, and flags
// are what's important.  The other variables are place holders so that the structure
// maintains the correct size when compared to the other possible input structure types.  
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct KEYBOARD_INPUT_FOR_32_BIT
{
    public ushort VirtualKeyCode;
    public ushort ScanCode;
    public uint Flags;
    public uint Time;
    public uint ExtraInfo;
    public uint Padding1;
    public uint Padding2;
}

// Here's the corresponding 64 bit structure.  Notice that the field offset are larger. 
[StructLayout(LayoutKind.Explicit, Pack = 1)]
internal struct SEND_INPUT_FOR_64_BIT
{
    [FieldOffset(0)]
    public uint InputType;
    [FieldOffset(8)]
    public KEYBOARD_INPUT_FOR_64_BIT KeyboardInputStruct;
}

// Here's the keyboard 64 bit structure.  Notice that the field offset are again larger.
[StructLayout(LayoutKind.Explicit, Pack = 1)]
internal struct KEYBOARD_INPUT_FOR_64_BIT
{
    [FieldOffset(0)]
    public ushort VirtualKeyCode;
    [FieldOffset(2)]
    public ushort ScanCode;
    [FieldOffset(4)]
    public uint Flags;
    [FieldOffset(12)]
    public uint Time;
    [FieldOffset(20)]
    public uint Padding1;
    [FieldOffset(28)]
    public uint Padding2;
} 

Здесь идет немного грязная часть.Какая структура используется, определяется архитектурой, в которой работает приложение.Вы можете скомпилировать для 32 или 64-битной цели, но вы все равно можете запустить 32-битное скомпилированное приложение в 64-битной Windows.Если вы хотите, чтобы ваше 32-битное скомпилированное приложение использовало SendInput на 64-битной машине, вы должны выяснить, какую структуру использовать во время выполнения.Я сделал это, проверив размер слова, когда был вызван мой открытый метод для отправки ввода.

    public static void SendInput( ushort charUnicode )
    {
        // In 32 bit the IntPtr should be 4; it's 8 in 64 bit.
        if (Marshal.SizeOf(new IntPtr()) == 8)
        {
            SendInput64(charUnicode);
        }
        else
        {
            SendInput32(charUnicode);
        }
    }

Я не пробовал это в Vista, но он работает в 32/64 Windows XP и 32/64 Windows7.

0 голосов
/ 18 августа 2011

Скомпилируйте ваш проект для 32-битной версии, чтобы исправить это.Пожалуйста, обратитесь к: http://social.msdn.microsoft.com/Forums/en-SG/Vsexpressvb/thread/69e5529e-372b-4d70-bb94-556507a2358e

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...