Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Thursday, November 20, 2014 8:23 AM
Hi,
I am referring SendInput win method from below code to send keystrokes over local and remote machine and it is working fine.
I could not find the way to send special key strokes e.g. (ALT, ENER, Home Key etc.) over local and Remote machine. I Please let me know how to achieve the same.
Thanks in advance for your help.
Regards,
Parveen
Regards, Parveen
All replies (10)
Wednesday, December 3, 2014 5:36 PM âś…Answered
Hi,
I am able to send special keys to remote desktop using below code. The only issue with this code is that if ALT/Shift/Controls keys are not getting released if any of these keys is passed.
class Program
{
static void Main(string[] args)
{
Thread.Sleep(3000);
int[] keyboardStrokes = { (int)Keys.LMenu, (int)Keys.Tab, (int)Keys.Tab };
ProcessKey(keyboardStrokes);
Console.Read();
}
struct INPUT
{
public INPUTType type;
public INPUTUnion Event;
}
[StructLayout(LayoutKind.Explicit)]
struct INPUTUnion
{
[FieldOffset(0)]
internal MOUSEINPUT mi;
[FieldOffset(0)]
internal KEYBDINPUT ki;
[FieldOffset(0)]
internal HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
public int dx;
public int dy;
public int mouseData;
public int dwFlags;
public uint time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct KEYBDINPUT
{
public ushort wVk;
public ushort wScan;
public KEYEVENTF dwFlags;
public int time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
struct HARDWAREINPUT
{
public int uMsg;
public short wParamL;
public short wParamH;
}
enum INPUTType : uint
{
INPUT_KEYBOARD = 1
}
[Flags]
enum KEYEVENTF : uint
{
EXTENDEDKEY = 0x0001,
KEYUP = 0x0002,
SCANCODE = 0x0008,
UNICODE = 0x0004
}
[DllImport("user32.dll", SetLastError = true)]
static extern UInt32 SendInput(int numberOfInputs, INPUT[] inputs, int sizeOfInputStructure);
[System.Runtime.InteropServices.DllImport("user32.dll")]
internal static extern uint MapVirtualKey(uint uCode, uint uMapType);
private static void ProcessKey(int[] key)
{
INPUT[] inputs = new INPUT[key.Length + 1];
for (int i = 0; i < key.Length; i++)
{
uint skey = MapVirtualKey((uint)key[i], (uint)0x0);
inputs[i].type = INPUTType.INPUT_KEYBOARD;
inputs[i].Event.ki.dwFlags = KEYEVENTF.SCANCODE;
inputs[i].Event.ki.wScan = (ushort)skey;
}
inputs[key.Length].type = INPUTType.INPUT_KEYBOARD;
inputs[key.Length].Event.ki.dwFlags = KEYEVENTF.UNICODE;
inputs[key.Length].Event.ki.dwFlags |= KEYEVENTF.KEYUP;
uint cSuccess = SendInput(inputs.Length, inputs, Marshal.SizeOf(typeof(INPUT)));
}
Regards, Parveen
Thursday, November 20, 2014 8:19 AM
Hi,
I am using Windows Input Simulator from the Codeplex.
http://inputsimulator.codeplex.com/
I am able to send normal text e.g (test, Microsoft etc.) over Remote Desktop Connection but unable to send special key strokes e.g. (ALT, ENER, Home Key etc.) over Remote Desktop Connection. I am able to send special key strokes on local machine. Please let me know how to achieve the same over Remote Desktop Connection.
Regards,
Parveen
Regards, Parveen
Thursday, November 20, 2014 8:47 AM
Because by default these key combination will not be sent to the remote side.
See if changing the following setting works for you:
http://superuser.com/questions/547264/remote-desktop-connection-alt-key-is-blocked
And not that in all case Ctrl-Alt-Del is never sent (because it's captured by Windows itself and never reach the RDP client), so in that case you'll require the user to use Ctrl-Alt-End instead.
EDIT: Try set .AdvancedSettings2.AccelaratorPassthrough property for the programmatic way:
http://msdn.microsoft.com/en-us/library/aa380855(v=vs.85).aspx
Friday, November 21, 2014 6:47 AM
Hi Parveen,
Let's do a sample using SendInput and send key strokes e.g.(Lwin+R), It will show a run window at the lower left corner. You can use Keys.ShiftKey, Keys.ControlKey and Keys.Home instead. And I have tested on my side, It works fine on my local machine, please also have a try.
public partial class Form1 : Form
{
[DllImport("user32.dll")]
public static extern UInt32 SendInput(UInt32 nInputs, INPUT[] pInputs, int cbSize);
[DllImport("kernel32.dll")]
public static extern int GetTickCount();
[StructLayout(LayoutKind.Explicit)]
public struct INPUT
{
[FieldOffset(0)]
public Int32 type;
[FieldOffset(4)]
public KEYBDINPUT ki;
[FieldOffset(4)]
public MOUSEINPUT mi;
[FieldOffset(4)]
public HARDWAREINPUT hi;
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEINPUT
{
public Int32 dx;
public Int32 dy;
public Int32 mouseData;
public Int32 dwFlags;
public Int32 time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct KEYBDINPUT
{
public Int16 wVk;
public Int16 wScan;
public Int32 dwFlags;
public Int32 time;
public IntPtr dwExtraInfo;
}
[StructLayout(LayoutKind.Sequential)]
public struct HARDWAREINPUT
{
public Int32 uMsg;
public Int16 wParamL;
public Int16 wParamH;
}
public const int INPUT_KEYBOARD = 1;
public const int KEYEVENTF_KEYUP = 0x0002;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
INPUT[] inDown = new INPUT[4];
inDown[0] = new INPUT();
inDown[1] = new INPUT();
inDown[2] = new INPUT();
inDown[3] = new INPUT();
inDown[0].type = inDown[1].type = inDown[2].type = inDown[3].type = INPUT_KEYBOARD;
inDown[0].ki.wVk = inDown[2].ki.wVk = (int)Keys.LWin;
inDown[1].ki.wVk = inDown[3].ki.wVk = (int)Keys.D;
inDown[2].ki.dwFlags = inDown[3].ki.dwFlags = KEYEVENTF_KEYUP;
//SendInput(4, inDown, Marshal.SizeOf(inDown[0]));
this.Text = Form1.SendInput(4, inDown, Marshal.SizeOf(inDown[0])).ToString();
}
}
Thanks&&Kristin
We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
Click HERE to participate the survey.
Monday, November 24, 2014 12:51 PM
Thanks Kristin.
I am also able to pass Special keys on local machine but the same is not working on remote machines. Please provide any pointers to resolve this issue.
Regards, Parveen
Wednesday, November 26, 2014 1:57 PM | 1 vote
Hi
you can check this post:http://stackoverflow.com/questions/3554171/cant-send-a-single-key-function-to-remote-desktop
I'm not tried yet, but I the answer is resonable.
I also have an idea but it need you to write another application in the remote machine which can just reveice your key code and send the keys locally.
Thursday, November 27, 2014 1:59 AM
Actually I remembered that I read somewhere that you should use SendKey() if it's available to your situation, because it creates all necessary events in correct order for you. (The highlighted part is important. Say if you misplaced the WM_CHAR message, some application may not be able to decode the scan code and execute associated actions)
Thursday, November 27, 2014 6:39 AM
Thanks. I am able to pass text to Remote desktop but not special keys. Please let me know how to pass special keys like ALT, Tab, F4 etc. to remote desktop. Tried with SendKeys as well but not working on remote machine.
Regards, Parveen
Thursday, November 27, 2014 6:39 AM
Tried with SendKeys but not working on remote machine.
Regards, Parveen
Friday, November 28, 2014 6:32 AM
By using PostMessage() to Main Window for these message, it seems to return error 5, indicates the message loop does not process these messages.
So you may need to use Spy++ to found out which of the child window is accepting input to send the message to it.
Just like notepad is a plain program hosting simple EDIT control, the remote desktop client is a simple program hosting remote desktop COM control. So you may have to find it out, see if it has any special indicator like different class name, and modify you program to use EnumChildWindow() + GetClassName() APIs.
And also note that since these are implementation details, it may or may not work in any past or future version of remote desktop.