title: SendKeys alternative that works on Citrix
body: <p>I recently developed a virtual keyboard application for a customer. The program is working fine with almost all programs, but certain commands like <code>{ENTER}</code> or <code>{DEL}</code> are not working with Citrix. Is there are workaround or an alternative to <code>SendKeys</code>?</p>
  
  <p>Edit 1: I tried the SendInput method (Windows Input Simulator uses SendInput) and the DEL key as well as the arrow keys are still not working. The ENTER key works however.</p>
  
  <p>Edit 2: Solved it. Tested with two different versions of Citrix. <a href="https://stackoverflow.com/questions/1032246/citrix-and-keybd-event-problem">This question helped me a lot.</a>:</p>
  
  <blockquote>
    <p>Citrix thin clients uses the scancode
    param of keybd_event even when MS says
    it is unused and should be 0. You need
    to supply the physical scancode aswell
    for the citrix client to get it.
    Citrix client also has major problem
    with keyboard input generated with the
    SendInput API.</p>
  </blockquote>
  
  <p>I patched the code in <a href="http://inputsimulator.codeplex.com/" rel="nofollow noreferrer">Windows Input Simulator</a>:</p>
  
  <pre><code>// Function used to get the scan code
  [DllImport("user32.dll")]
  static extern uint MapVirtualKey(uint uCode, uint uMapType);
  
  
  /// &lt;summary&gt;
  /// Calls the Win32 SendInput method ...
  /// &lt;/summary&gt;
  /// &lt;param name="keyCode"&gt;The VirtualKeyCode to press&lt;/param&gt;
  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));
  }
  </code></pre>