Send keypresses across the network - windows

I'd like to be able to send key presses from one computer to the other. I have a voice application on one system which I use for my headset, and the other system is my main system. The voice application uses a Push-to-talk (PTT) system, which I'd rather keep.
So what I'd like to do is press a key on my main system and have it sent across the network to my secondary system. At this stage all I know is how to get the key across the network, the specifics of actually detecting the key press on my main system and emulating the press on the secondary system is my problem.
The key I'd like to capture (when held down) and send to my secondary system is the right control key. I think the best way is to add a keyboard hook.
How can I do this in such a way that I can hit right control in any application on my main system and have this application pick that up and send it? When my secondary system receives the key, how do I send it to the entire system (rather than trying to find a specific application)? I'm fine with using low-level Win32 calls in unmanaged C++, I'd just like to know how to get this to work.
Thanks in advance.

It seems like you're already halfway there to your own custom solution, but as an alternate you might want to check out Synergy an open source keyboard and mouse extender.

I found the answer: I wrote a small keyboard hook to pick up the PTT press, and then send it via the network to the secondary system. The secondary system takes this keypress and uses the SendInput function to inject the key into the system input queue. I just tested it with Teamspeak and it works brilliantly.

Related

Win32 - How do I catch key event in background, without using global key hook or RegisterHotKey?

I made a program that takes a screenshot of a game window when a specific key is pressed. I am using RegisterHotKey(). It works well, but there is a problem: when the game window is on focus, my program can't receive that key event. To take a screenshot, I have to click the desktop to move the focus to desktop, then press that key. Only in that way can my program receive the key event and take a screenshot. (the game itself provides an in-game camera to take screenshots, but the camera can't take screenshots of UI, inventory, etc. That's why I made this program.)
It's a easy fix to use global key hook, but if I use global key hook, my program will be prone to be identified as a malware (that steals password, for example.) by anti-malware softwares, meaning that I can't share it with other players. (After all, for players that are not good at computer, it is tiring to convince Windows Defender that my program is not malware.)
Is there any idea to catch the key event, but won't make my program identified as a malware?
You can set up a global key monitor by using Raw Input. To do so you need to set the RIDEV_INPUTSINK flag in the RAWINPUTDEVICE structure passed into the RegisterRawInputDevices call.

How can I know hooked keyboard ID?

I have two keyboards connected on my computer. I want to use one for the main keyboard, and another for a specific application. For example, keyboard #1 is used for Windows, and keyboard #2 is used only in my application.
Is it possible? If yes, which language should I use? Do I need to access to the driver? I precise that I'm running under Windows...
I found a link that explain step by step how to intercept keyboard keys, and how to identify the device that sent the keystroke.
Using Raw Input from C# to handle multiple keyboards
This example uses C# language.

Window hooks and applications

Related to my question here, is it possible to create a window hook that will monitor if an application has been opened or not?
Most that I have found about hooks seem to focus on user input (keyboard press, mouse events), but I could not confirm if it is possible to know that the "double click" the user made is to open an application, or just to highlight a word.
Thank you.
Indeed, window hooks would not be sufficient. In fact for the task you are asking about you could use various strategies, such as:
enumerating the processes to find the one you're looking for (Tool Help API or PSAPI)
enumerating the top-level windows on the desktop (but you're limited to your desktop then)
check for a global or local event, mutex (or other kernel object) to deduce from that that some instance of the application is running
... or even from kernel PsSetCreateProcessNotifyRoutine
probably there are variations on the above plus some more.
In essence the question is whether you want to check for the process or for some other indicator that signifies whether the program you want to check for has been started.

What happens 'behind' the windows lock screen?

I have been working on windows automation and monitoring.
What exactly happens when I lock the screen of a windows machine?
I am working with Windows 7 at the moment, are there big differences to the behavior if I switch to Vista or the server versions?
Is there still a desktop that can be accessed via api's?
I know that i can still send key strokes and mouse clicks to specific windows (via ControlSend and ControlClick), but there seems to be no "desktop" itself.
Could someone shed some light on this whole thing or point me at a readable source where I could get an overview over the topic?
Basically what happens is that Windows switches to the secure desktop, makes it the current one, so input is now associated with it.
The old desktop remains where it was: all the HWNDs on the desktop are still there, and any thread attached to that desktop can still access those HWNDs, get their location, and so on. You can still send messages to windows on this desktop, so long as the thread sending the message is also on that desktop.
However, since the desktop is now inactive, it cannot receive input. GetForegroundWindow will return NULL (IIRC), and you can't use SendInput any longer, since input now belongs to [a thread on] a different desktop; no controls on that inactive desktop can receive focus.
Note that sending keypress messages to a control that doesn't have focus can sometimes cause unexpected behavior, since the app or control generally never expects to receive keyboard input without getting the focus first. (This can be problematic for controls that set up some sort of input context in WM_SETFOCUS and clear it up in WM_KILLFOCUS, for example.)
In short, the UI is still there: you can do certain queries against it, but you can no longer automate it as you could on a regular desktop by sending input, and some other functions that relate to focus or input may fail.
I'm not super familiar with AutoHotKey, but the name and description of functionality suggests that it's heavily reliant on the underlying Win32 SendInput API. This won't work at all for keyboard input when a desktop is inactive.
For a reasonable overview of how desktops work and how they relate to winstations, the locked desktop, and so on, check out the Desktop article on MSDN.
One issue that I've run into in the past with desktops and automation is: how to I leave a long-running test that's using some form of user input automation (mouse, keyboard simulation), but still lock my PC so that someone can't just walk by and interfere with it. Once you lock the PC, the desktop is inactive, and so the automation stops working. A similar issue happens if the screensaver kicks in: the desktop switches, and the automation fails.
One solution is to use two PCs: let's call them Main and Test: from Main, open a remote terminal services client onto the Test machine, and then run the automated test on the test machine, but from a terminal services client window on the Main machine. Now the cool part: you can minimize that TSC window, or even lock the Main machine (or let the screensaver kick in), and that virtual session will continue working, thinking that it is still active - it's just that nobody is paying it any attention. This is one way to create a "connected" session with an active desktop, but one that no-one can interfere with, because it's protected behind the locked desktop of the Main machine.
I don't know the details, but I believe the lock screen constitutes a separate "desktop" and maybe also a separate "window station" (as I understand it a window station is merely a container for desktops). The MSDN section on window stations should hopefully be useful: http://msdn.microsoft.com/en-us/library/windows/desktop/ms687098%28v=vs.85%29.aspx
In order to access a desktop, you will need to use the regular windows api's from a thread that is on that desktop. SetThreadDesktop would probably be the easiest way to do that in C, as long as the desktop isn't on a different window station.
Unfortunately, this is already difficult for a regular privileged application, and using AutoHotkey complicates it even more. Since you don't have control over threads or over process initialization, you will probably have to create a new process in the other desktop (you can do this using the CreateProcess API, which appears to have a wrapper available for AHK to which you can supply a desktop name: http://www.autohotkey.com/forum/topic1952.html). Your process will need special privileges to do this; I'm not sure that even running as Administrator is enough.

How to programmatically detect a system hotkey?

I'm looking for a way to programmatically detect hotkeys in the system. My app supports configurable hotkeys to do different things, and I'd like to be able to tell if another app has snagged one already or it's a built-in Windows hotkey (like Win-L to lock the workstation).
And if it is another app that owns the hotkey, I'd like to be able to show that to the user. At least the name of the exe.
I'm aware of three ways to do hotkeys:
System hook using standard API's
Using the hotkey feature in the properties dialog for a shortcut
Polling async key state and responding
I doubt I can detect the third type, but what about the other two? And are there any other situations I need to know about?
I can think of three ways to do it with Standard API:
RegisterHotkey
SetWindowsHookEx(WH_KEYBOARD)
SetWindowsHookEx(WH_LL_KEYBOARD)
With the first approach, you will get in the return value whether another application already registered the very same hotkey (or whether a shortcut uses this hotkey, or Explorer.exe registered the hotkey because it is Win+E or win+R). You don't get the application name this way, though.
Using Windows Hooks or async key states for "hotkeys": I don't think it is possible to detect hotkeys there, since you might use hotkeys in a context (like replace "t" by "irst" if the last four keystrokes were "Fris") that way. You could inject the hotkey using keybd_event (with your window focused) and test if the event "gets through"; on the other hands, some cases of "hotkeys" that are implemented via hooks do not consume the keystroke so it will still get through.
The approach I would use: First make sure that for entering a shortcut, you have to type that exact shortcut into your shortcut box (if that fails, the user will see which application uses it). Then use RegisterHotkey, so you will notice (in future sessions) if another "well-behaving" application tried to steal this shortcut from you.

Resources