2011-02-17 6 views
13

पर काम करता है मैंने हाल ही में एक ग्राहक के लिए वर्चुअल कीबोर्ड एप्लिकेशन विकसित किया है। कार्यक्रम लगभग सभी कार्यक्रमों के साथ ठीक काम कर रहा है, लेकिन कुछ आदेश जैसे {ENTER} या {DEL} साइट्रिक्स के साथ काम नहीं कर रहे हैं। क्या वर्कअराउंड या SendKeys का विकल्प है?SendKeys वैकल्पिक जो सिट्रिक्स

संपादित करें 1: मैंने SendInput विधि (विंडोज इनपुट सिम्युलेटर SendInput का उपयोग करता है) और डीएल कुंजी के साथ-साथ तीर कुंजियां अभी भी काम नहीं कर रही हैं। हालांकि एंटर कुंजी काम करता है।

संपादित करें 2: इसे हल करें। साइट्रिक्स के दो अलग-अलग संस्करणों के साथ परीक्षण किया गया। This question helped me a lot.:

Citrix थिन क्लाइंट scancode keybd_event की परम का उपयोग करता है, तब भी जब एमएस कहते यह अप्रयुक्त है और 0. आप जरूरत है इसे पाने के लिए Citrix ग्राहक के लिए रूप में अच्छी तरह शारीरिक scancode आपूर्ति करने के लिए किया जाना चाहिए। साइट्रिक्स क्लाइंट में भी SendInput API के साथ उत्पन्न कुंजीपटल इनपुट के साथ बड़ी समस्या है।

मैं Windows Input Simulator में कोड समझौता:

// Function used to get the scan code 
[DllImport("user32.dll")] 
static extern uint MapVirtualKey(uint uCode, uint uMapType); 


/// <summary> 
/// Calls the Win32 SendInput method ... 
/// </summary> 
/// <param name="keyCode">The VirtualKeyCode to press</param> 
public static void SimulateKeyPress(VirtualKeyCode keyCode) 
{ 
    var down = new INPUT(); 
    down.Type = (UInt32)InputType.KEYBOARD; 
    down.Data.Keyboard = new KEYBDINPUT(); 
    down.Data.Keyboard.Vk = (UInt16)keyCode; 
    // Scan Code here, was 0 
    down.Data.Keyboard.Scan = (ushort) MapVirtualKey((UInt16)keyCode, 0); 
    down.Data.Keyboard.Flags = 0; 
    down.Data.Keyboard.Time = 0; 
    down.Data.Keyboard.ExtraInfo = IntPtr.Zero; 

    var up = new INPUT(); 
    up.Type = (UInt32)InputType.KEYBOARD; 
    up.Data.Keyboard = new KEYBDINPUT(); 
    up.Data.Keyboard.Vk = (UInt16)keyCode; 
    // Scan Code here, was 0 
    up.Data.Keyboard.Scan = (ushort)MapVirtualKey((UInt16)keyCode, 0); 
    up.Data.Keyboard.Flags = (UInt32)KeyboardFlag.KEYUP; 
    up.Data.Keyboard.Time = 0; 
    up.Data.Keyboard.ExtraInfo = IntPtr.Zero; 

    INPUT[] inputList = new INPUT[2]; 
    inputList[0] = down; 
    inputList[1] = up; 

    var numberOfSuccessfulSimulatedInputs = SendInput(2, 
     inputList, Marshal.SizeOf(typeof(INPUT))); 
    if (numberOfSuccessfulSimulatedInputs == 0) 
     throw new Exception(
     string.Format("The key press simulation for {0} was not successful.", 
     keyCode)); 
} 
+2

धन्यवाद XSL पारित कर दिया आभासी कुंजी के साथ जुड़े कोड स्कैन भेज देंगे !!! महान खोजें! मैं भी इनपुट सिम्युलेटर (फैब टूल बीटीडब्ल्यू) का उपयोग कर रहा था, लेकिन मुझे आपके द्वारा प्रदान की गई इस चिमटा की आवश्यकता है (ushort) MapVirtualKey ((UInt16) keyCode, 0); उत्कृष्ट कार्य - बहुत धन्यवाद –

+0

क्या आपके पास एक कीप्रेस की बजाय पूरी स्ट्रिंग भेजने का कोई तरीका है? – Mathias

उत्तर

8

Windows Input Simulator. सुनिश्चित नहीं हैं का उपयोग कर अगर यह Citrix समर्थन करता है, लेकिन यह SendKeys की तुलना में बहुत अधिक शक्तिशाली है की कोशिश करें। API कॉल WIA पी आह्वान हस्ताक्षर का उपयोग करने के

+0

आपकी त्वरित प्रतिक्रिया के लिए धन्यवाद। मैं कोशिश करूँगा और आपको परिणाम बताऊंगा। – xsl

3

कोशिश (सामग्री संपादित: यह अब काम कर रहा है उदाहरण - मैं 'एक' पाठ बॉक्स के लिए चरित्र भेज रहा, एक बटन के क्लिक पर):

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Text; 
using System.Windows.Forms; 
using System.Runtime; 
using System.Runtime.InteropServices; 

namespace Test2 
{ 
    public partial class Form1 : Form 
    { 
     [StructLayout(LayoutKind.Sequential)] 
     public struct KEYBOARD_INPUT 
     { 
      public const uint Type = 1; 
      public ushort wVk; 
      public ushort wScan; 
      public uint dwFlags; 
      public uint time; 
      public IntPtr dwExtraInfo; 
     } 

     [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.Explicit)] 
     struct KEYBDINPUT 
     { 
      [FieldOffset(0)] 
      public ushort wVk; 
      [FieldOffset(2)] 
      public ushort wScan; 
      [FieldOffset(4)] 
      public uint dwFlags; 
      [FieldOffset(8)] 
      public uint time; 
      [FieldOffset(12)] 
      public IntPtr dwExtraInfo; 
     }; 

     [StructLayout(LayoutKind.Sequential)] 
     struct HARDWAREINPUT 
     { 
      public uint uMsg; 
      public ushort wParamL; 
      public ushort wParamH; 
     }; 

     [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; 
     }; 
     [DllImport("user32.dll", SetLastError = true)] 
     static extern uint SendInput(uint nInputs, IntPtr pInput, int cbSize); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      textBox1.Focus(); 
      INPUT Input = new INPUT(); 

      Input.type = 1; 
      Input.ki.wVk = 0x41; //ASCII for letter 'A' 
      Input.ki.dwFlags = 0; //Key is pressed down 
      Input.ki.dwExtraInfo = IntPtr.Zero; 
      IntPtr pInput; 
      pInput = Marshal.AllocHGlobal(Marshal.SizeOf(Input)); 

      Marshal.StructureToPtr(Input, pInput, false); 
      SendInput(1, pInput, Marshal.SizeOf(Input)); 
      Input.ki.dwFlags = 2; //Key is released on the keyboard 

      Marshal.StructureToPtr(Input, pInput, false); 
      SendInput(1, pInput, Marshal.SizeOf(Input)); 
     } 
    } 
} 
3

मैं विंडोज इनपुटपुट सिम्युलेटर लाइब्रेरी का उपयोग कर एक साइट्रिक्स एप्लिकेशन को नियंत्रित करने का भी प्रयास कर रहा हूं। ऊपर दिया गया आपका कोड वादाजनक लग रहा था, इसलिए मैंने इसे इनपुट सिम्युलेटर के नवीनतम संस्करण के साथ काम करने के लिए अपडेट किया (जहां आप सिंप.किबोर्ड का उपयोग करते हैं। इनपुट सिम्युलेटर के बजाय कीपर। सिम्युलेटकेपप्रेस)। यहां कोड है जिसे मैंने इनपुट सिम्युलेटर में जोड़ा है, और मुझे यह रिपोर्ट करने में प्रसन्नता हो रही है कि यह अपेक्षित रूप से काम करता है, और ऐसी समस्या हल करती है जिसे मैंने पहले सोचा था। बहुत बहुत धन्यवाद।

IKeyboardSimulator.cs में:

/// <summary> 
    /// Simulates the key press gesture for the specified key. 
    /// </summary> 
    /// <param name="keyCode">The <see cref="VirtualKeyCode"/> for the key.</param> 
    IKeyboardSimulator CITRIXKeyPress(VirtualKeyCode keyCode); 

KeyboardSimulator.cs में:

using System.Runtime.InteropServices; 

    . 
    . 
    . 

    // CITRIX HACK 
    // Function used to get the scan code 
    [DllImport("user32.dll")] 
    static extern uint MapVirtualKey(uint uCode, uint uMapType); 

    [DllImport("User32.dll")] 
    private static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] input, int structSize); 


    /// <summary> 
    /// Calls the Win32 SendInput method ... 
    /// </summary> 
    /// <param name="keyCode">The VirtualKeyCode to press</param> 
    public IKeyboardSimulator CITRIXKeyPress(VirtualKeyCode keyCode) //prev public static void 
    { 
     var down = new INPUT(); 
     down.Type = (UInt32)InputType.Keyboard; 
     down.Data.Keyboard = new KEYBDINPUT(); 
     down.Data.Keyboard.KeyCode = (UInt16)keyCode; //prev .Keyboard.Vk 
     // Scan Code here, was 0 
     down.Data.Keyboard.Scan = (ushort)MapVirtualKey((UInt16)keyCode, 0); 
     down.Data.Keyboard.Flags = 0; 
     down.Data.Keyboard.Time = 0; 
     down.Data.Keyboard.ExtraInfo = IntPtr.Zero; 

     var up = new INPUT(); 
     up.Type = (UInt32)InputType.Keyboard; 
     up.Data.Keyboard = new KEYBDINPUT(); 
     up.Data.Keyboard.KeyCode = (UInt16)keyCode; 
     // Scan Code here, was 0 
     up.Data.Keyboard.Scan = (ushort)MapVirtualKey((UInt16)keyCode, 0); 
     up.Data.Keyboard.Flags = (UInt32)KeyboardFlag.KeyUp; 
     up.Data.Keyboard.Time = 0; 
     up.Data.Keyboard.ExtraInfo = IntPtr.Zero; 

     INPUT[] inputList = new INPUT[2]; 
     inputList[0] = down; 
     inputList[1] = up; 

     var numberOfSuccessfulSimulatedInputs = SendInput(2, 
      inputList, Marshal.SizeOf(typeof(INPUT))); 
     if (numberOfSuccessfulSimulatedInputs == 0) 
      throw new Exception(
      string.Format("The key press simulation for {0} was not successful.", 
      keyCode)); 
     return this; 
    } 
+0

मैं एक ही चीज की कोशिश कर रहा हूं आलोचकों के लिए एक स्ट्रिंग भेज रहा हूं, मैं आपके कोड में स्ट्रिंग मान कैसे पास करूं – prasy

0

खिड़कियों इनपुट सिम्युलेटर समाधान के लिए, आप इतना है कि कार्यों में बनाया भेज देंगे सीधे स्रोत कोड को संशोधित कर सकते आभासी कुंजी के साथ कोड स्कैन करें।

InputBuilder.cs:।

using System.Runtime.InteropServices; 

. 
. 
. 

[DllImport("user32.dll")] 
static extern uint MapVirtualKey(uint uCode, uint uMapType); 

. 
. 
. 

public InputBuilder AddKeyDown(VirtualKeyCode keyCode) 
{ 
    var down = 
     new INPUT 
     { 
      Type = (UInt32)InputType.Keyboard, 
      Data = 
        { 
         Keyboard = 
          new KEYBDINPUT 
           { 
            KeyCode = (UInt16) keyCode, 
            Scan = (UInt16)MapVirtualKey((UInt16)keyCode, 0), 
            Flags = IsExtendedKey(keyCode) ? (UInt32) KeyboardFlag.ExtendedKey : 0, 
            Time = 0, 
            ExtraInfo = IntPtr.Zero 
           } 
        } 
      }; 

    _inputList.Add(down); 
    return this; 
} 

public InputBuilder AddKeyUp(VirtualKeyCode keyCode) 
{ 
    var up = 
     new INPUT 
      { 
       Type = (UInt32) InputType.Keyboard, 
       Data = 
        { 
         Keyboard = 
          new KEYBDINPUT 
           { 
            KeyCode = (UInt16) keyCode, 
            Scan = (UInt16)MapVirtualKey((UInt16)keyCode, 0), 
            Flags = (UInt32) (IsExtendedKey(keyCode) 
                  ? KeyboardFlag.KeyUp | KeyboardFlag.ExtendedKey 
                  : KeyboardFlag.KeyUp), 
            Time = 0, 
            ExtraInfo = IntPtr.Zero 
           } 
        } 
      }; 

    _inputList.Add(up); 
    return this; 
} 

इन परिवर्तनों के साथ KeyPress और ModifiedKeyStroke में

संबंधित मुद्दे