public void DoKeyboardAction(RemoteDesktopKeyboardAction keyboardAction, short scanCode)
        {
            INPUT keyboardInput = new INPUT();

            keyboardInput.type         = InputType.KEYBOARD;
            keyboardInput.U.ki.wScan   = scanCode;
            keyboardInput.U.ki.dwFlags = KEYEVENTF.SCANCODE;

            if (keyboardAction == RemoteDesktopKeyboardAction.KeyUp)
            {
                keyboardInput.U.ki.dwFlags |= KEYEVENTF.KEYUP;
            }

            keyboardInput.U.ki.dwExtraInfo = UIntPtr.Zero;
            keyboardInput.U.ki.time        = 0;

            SendIput(keyboardInput);
        }
        //https://stackoverflow.com/questions/11890972/simulating-key-press-with-postmessage-only-works-in-some-applications
        public void DoKeyboardAction(RemoteDesktopKeyboardAction keyboardAction, short scanCode, long windowHandle)
        {
            Desktop.SetCurrent(Desktop);

            var guidThreadInfo = new GUITHREADINFO();

            guidThreadInfo.cbSize = Marshal.SizeOf(guidThreadInfo);

            var currentWindow = new IntPtr(windowHandle);

            var threadId = NativeMethods.GetWindowThreadProcessId(currentWindow, IntPtr.Zero);
            var result   = NativeMethods.GetGUIThreadInfo(threadId, ref guidThreadInfo);

            if (!result)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            currentWindow = guidThreadInfo.hwndFocus;

            var virtualKeyCode = NativeMethods.MapVirtualKey((uint)scanCode, MapVirtualKeyMapTypes.MAPVK_VSC_TO_VK);

            //https://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx#CodeSnippetContainerCode0
            var lparam = scanCode >> 16;

            switch (keyboardAction)
            {
            case RemoteDesktopKeyboardAction.KeyDown:
                NativeMethods.PostMessage(new HandleRef(null, currentWindow), WM.KEYDOWN, new IntPtr(virtualKeyCode),
                                          new IntPtr(lparam));
                break;

            case RemoteDesktopKeyboardAction.KeyUp:
                //that makes every key doubled
                //NativeMethods.PostMessage(new HandleRef(null, currentWindow), WM.KEYUP, new IntPtr(virtualKeyCode),
                //    new IntPtr(lparam));
                break;

            default:
                throw new ArgumentOutOfRangeException(nameof(keyboardAction), keyboardAction, null);
            }
        }