2011-01-04 2 views
1

Я использовал sendInput() под xp 32bits, используя webservices, чтобы нажать F5 текущих сфокусированных окон. Теперь под Vista win64 я не могу получить этот результат. Некоторые статьи указывают на проблемы uint с использованием 4 бит или 8 бит, но это не устраняет проблему под Vista с дифференциальной компиляцией и FieldOffset (4) или (8). Другие говорят об отсутствии взаимодействия между экраном Vista и окном, используя этот метод SendInput(). Может ли кто-то указать на решение нажать F5 в win32 и win64. Благодарю.SendInput Keys в машинах 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); 

}

+0

Пожалуйста, покажите нам свои объявления. – SLaks

+2

Действие: нажмите F5 из веб-приложения под Vista64 и после Win7-64. – user325558

+1

Этот парень, похоже, получил его на работу. http://social.msdn.microsoft.com/Forums/en/windowscompatibility/thread/627b1c8c-0b75-4f73-9e29-3e17e93d539a –

ответ

3

Я столкнулся с этой проблемой с 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, но он работает в Windows XP 32/64 и 32/64 под управлением Windows 7.

+0

[более простое решение объясняется на pinvoke.net] (http://www.pinvoke.net/default.aspx/Structures/INPUT.html), где объединение помещается в отдельную структуру, чтобы автоматически решить эту проблему выравнивания : «Разделив объединение на свою структуру, вместо того, чтобы помещать поля mi, ki и hi непосредственно в структуру INPUT, мы гарантируем, что структура .Net будет иметь правильное выравнивание как на 32, так и на 64 бит». _ –

+0

Где методы SendInput64 (char any) и SendInput32 (char any)? – reggaeguitar

+0

@reggaeguitar Я их не перечислил, но они очень просты. Это просто вспомогательные методы, которые делают внешний вызов с соответствующей структурой для судороги системы. – CaulynDarr

Смежные вопросы