i'm trying to send fake keyboard input to an application that's running in a Remote Desktop session. i'm using:
Byte key = Ord("A");
keybd_event(key, 0, 0, 0); // key goes down
keybd_event(key, 0, KEYEVENTF_KEYUP, 0); // key goes up
Now this code does send the character "a" to any local window, but it will not send to the remote desktop window.
What that means is i use Remote Desktop to connect to a server, and i then open Notepad on that server. If i manually punch keys on the keyboard: they appear in Notepad's editor window. But keybd_event's fake keyboard input not causing "a"'s to appear in Notepad.
How can i programtically send fake keyboard input to an application running inside a remote desktop connection, from an application running on the local machine?
Nitpickers Corner
In this particular case i want to do this becase i'm trying to defeat an idle-timeout. But i could just as well be trying to
perform UI automation tests
UI stress tests
UI fault finding tests
UI unit tests
UI data input tests
UI paint tests
or UI resiliance tests.
In other words, my reasons for wanting it aren't important
Note: The timeout may be from remote desktop inactivity, or perhaps not. i don't know, and it doesn't affect my question.
Answer
Although Microsft says you don't need to, and you should not, send the OEM code, you need to send the OEM scan codes. In this example i need to send the OEM scan codes for
key A goes down
key A goes up
There is a picture of a chart on CodeProject that lists the make and break scan codes for various keys:
In my case the original calls to keybd_event need to be changed to:
Byte key = Ord("A");
keybd_event(key, 0x1E, 0, 0); // key goes down
keybd_event(key, 0x9E, KEYEVENTF_KEYUP, 0); // key goes up
i tested this, and it works. So all is well.
May be you can execute an autoit script with PsExec, a light-weight telnet-replacement that lets you execute processes on other systems, complete with full interactivity for console applications, without having to manually install client software.
(AutoIt is quite capable to send any signal (keys or other) to any window application, and could be launched with PsExec on the remote desktop)
An AutoIt script like KillSaver, for instance, is designed to move the mouse to avoid any prolong idle time on a computer!
This worked very well thank you. In order to get the keyboard scan code one can use:
int scan;
scan = MapVirtualKey(key & 0xff, 0);
keybd_event(key, scan, 0, 0); // key goes down
keybd_event(key, scan | 0x80, KEYEVENTF_KEYUP, 0); // key goes up
You could use SendMessage();
It's really a much better simulator for keys.
Well, good luck on this!
Related
Given this statement:
if (GetKeyState(VK_CAPITAL) & 0x8000)
{
cout << "caps lock" << endl;
}
It works fine if I press caps lock alone, or along with any key except ctrl. I was thinking it's because ctrl is a modifier, but this works fine when holding shift. Is there something I'm missing?
GetKeyState() provides the synchronized state of the keyboard. The state of all the keys when the key was pressed. It can take a while before your program sees it, Windows provides type-ahead, so it is important that the state of all keys is known to reliably detect whether Shift, Alt, Ctrl were down at the time.
The synchronized state gets updated when you call GetMessage(). Done in the boilerplate message loop of a Windows program.
But since you use cout, you probably wrote a console mode program and don't use a message loop at all. So it doesn't update. And you'll have to use GetAsyncKeyState(). No buffering at all, so you have to call it often. Do note that the console also has a way to retrieve keystrokes with buffering supported. Probably what you really want/should do when you write code like this. Watch out for input redirection.
I desire to construct a Hexapod which utilizes Arduino and is remotely controlled via Bluetooth, at present I am writing the code for its walking(in Arduino part),however I do not know how to proceed.The problem is as follow:
When a new command is received from the remote device I want the legs to stop what they are doing and carry out the received command.If this action is realized with Interrupts then after the command has been completed the previous process again starts,which is undesired for me. What can be done?
Thanks in advance for your answers.
The arduino doesn't really have separate processes - or even an OS.
You should think in terms of "states". Have a global (sorry) int representing the current state (use an enum) then when you do a new command set the state to the new command and return, then have a main loop which checks the state and performs whatever function is needed.
I'm trying to use RegNotifyChangeKeyValue to monitor changes of a 64-bit registry key.
To open this key from a 32-bit application, we must add the access flag KEY_WOW64_64KEY.
Unfortunately I can't seem to be able to monitor changes to this key, only it's 32-bit counterpart.
I'm including a demo project along with the unit I'm using to implement registry monitoring. Download it here: RegMonitor
Steps to reproduce the problem:
Compile the program. Run it as administrator. Click the Start button.
Open regedit and navigate to
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
Add a new value there. RegMonitor will not detect any change.
Navigate to
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Run
Add a new value there. RegMonitor will detect this change.
I've added the KEY_WOW64_64KEY access flag when opening the registry, but it still does not notify of any changes to correct key, only the Wow6432Node redirect.
Any idea if it's possible to use RegNotifyChangeKeyValue to monitor such key?
The following minimal example detects changes in the 64 bit view of the registry, from a 32 bit process. I don't know what's different about your program, but this code proves that a 32 bit program can indeed detect changes in both views.
I know this doesn't solve you problem, but I hope it helps steer you in the right direction.
program RegMonitor;
{$APPTYPE CONSOLE}
uses
SysUtils, Windows;
procedure Main;
const
dwFilter: DWORD =
REG_NOTIFY_CHANGE_NAME or
REG_NOTIFY_CHANGE_ATTRIBUTES or
REG_NOTIFY_CHANGE_LAST_SET or
REG_NOTIFY_CHANGE_SECURITY;
var
Error: Integer;
key: HKEY;
begin
Error := RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
'Software\Microsoft\Windows\CurrentVersion\RunOnce',
0,
KEY_NOTIFY or KEY_WOW64_64KEY,
key
);
if Error<>ERROR_SUCCESS then
RaiseLastOSError(Error);
try
Error := RegNotifyChangeKeyValue(
key,
True,
dwFilter,
0,
False
);
if Error<>ERROR_SUCCESS then
RaiseLastOSError(Error);
Writeln('Change detected');
Readln;
finally
RegCloseKey(key);
end;
end;
begin
Main;
end.
Now, as for your program, it looks like there are lots of problems with it. But the fundamental problem, the one that means you are not notified of changes, is that your event is created incorrectly. You create it like this:
CreateEvent(Nil, True, False, 'RegistryChangeMonitorEvent')
but you need to create it like this
CreateEvent(nil, True, False, nil)
I've not delved into what the requirements are for this event, the documentation does not offer any clues. All I did was look for differences between your code and the code in the MSDN example.
Make that change to the event creation and you have enough to start receiving notifications. However, when I did that change, your program still did not work and failed with an AV. One of your objects was not created. However, I think those are pretty routine bugs that you can sort out for yourself.
I wonder why you are using KEY_ALL_ACCESS. Why don't you use KEY_NOTIFY when you open the key to be passed to RegNotifyChangeKeyValue? And when you try to build a report of what has changed in a key, why don't you use KEY_READ? Since you are not attempting to write ever, KEY_ALL_ACCESS is not appropriate. If you make these changes then you won't need to run as admin.
I've made an interface to a NES Controller with an atxmega, which send the keys through serial. The problem lies in the program that reads the input and sends keybd_events accordingly.
if(szBuff[0] & BTN_LEFT) {
keybd_event(VkKeyScan('j'), 0, 0, 0);
keybd_event(VkKeyScan('j'), 0, KEYEVENTF_KEYUP, 0);
}
Problem is, it fails to get recognized as a 'j' in a NES emulator, while it does so in say a browser.
Hard to answer this without you explaining how the Nintendo emulator works. But you'll have to provide the virtual key code to VkKeyScan(). Which is 'J', not 'j'. As long as the Shift key isn't pressed, Windows will translate that to a WM_CHAR message that generates a 'j'.
Note that keybd_event() takes a virtual key and a scan code. You are passing the scan code as the virtual key. Fix:
keybd_event('J', VkKeyScan('J'), 0, 0);
Does anyone know if there is an API to get the current monitor state (on or off) in Windows (XP/Vista/2000/2003)?
All of my searches seem to indicate there is no real way of doing this.
This thread tries to use GetDevicePowerState which according to Microsoft's docs does not work for display devices.
In Vista I can listen to GUID_MONITOR_POWER_ON but I do not seem to get events when the monitor is turned off manually.
In XP I can hook into WM_SYSCOMMAND SC_MONITORPOWER, looking for status 2. This only works for situations where the system triggers the power off.
The WMI Win32_DesktopMonitor class does not seem to help out as well.
Edit: Here is a discussion on comp.os.ms-windows.programmer.win32 indicating there is no reliable way of doing this.
Anyone else have any other ideas?
GetDevicePowerState sometimes works for monitors. If it's present, you can open the \\.\LCD device. Close it immediately after you've finished with it.
Essentially, you're out of luck—there is no reliable way to detect the monitor power state, short of writing a device driver and filtering all of the power IRPs up and down the display driver chain. And that's not very reliable either.
You could hook up a webcam, point it at your screen and do some analysis on the images you receive ;)
Before doing anything based on the monitor state, just remember that users can use a machine with remote desktop of other systems that don't require a monitor connected to the machine - so don't turn off any visualization based on the monitor state.
You can't.
Look like all monitor power capabilities connected to the "power safe mode"
After searching i found here code that connecting between SC_MONITORPOWER message and system values (post number 2)
I use the code to testing if the system values is changing when i am manually switch off the monitor.
int main()
{
for(;monitorOff()!=1;)
Sleep(500);
return 0;
}//main
And the code is never stopped, no matter how long i am switch off my monitor.
There the code of monitorOff function:
int monitorOff()
{
const GUID MonitorClassGuid =
{0x4d36e96e, 0xe325, 0x11ce,
{0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
list<DevData> monitors;
ListDeviceClassData(&MonitorClassGuid, monitors);
list<DevData>::iterator it = monitors.begin(),
it_end = monitors.end();
for (; it != it_end; ++it)
{
const char *off_msg = "";
//it->PowerData.PD_PowerStateMapping
if (it->PowerData.PD_MostRecentPowerState != PowerDeviceD0)
{
return 1;
}
}//for
return 0;
}//monitorOff
Conclusion : when you manually switch of the the monitor, you cant catch it by windows (if there is no unusual driver interface for this), because all windows capabilities is connected to "power safe mode".
In Windows XP or later you can use the IMSVidDevice Interface.
See
http://msdn.microsoft.com/en-us/library/dd376775(VS.85).aspx
(not sure if this works in Sever 2003)
With Delphi code, you can detect invalid monitor geomerty while standby in progress:
i := 0
('Monitor'+IntToStr(i)+': '+IntToStr(Screen.Monitors[i].BoundsRect.Left)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Top)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Right)+', '+
IntToStr(Screen.Monitors[i].BoundsRect.Bottom))
Results:
Monitor geometry before standby:
Monitor0: 0, 0, 1600, 900
Monitor geometry while standby in Deplhi7:
Monitor0: 1637792, 4210405, 31266576, 1637696
Monitor geometry while standby in DeplhiXE:
Monitor0: 4211194, 40, 1637668, 1637693
This is a really old post but if it can help someone, I have found a solution to detect a screen being available or not : the Connecting and Configuring Displays (CCD) API of Windows.
It's part of User32.ddl and the interesting functions are GetDisplayConfigBufferSizes and QueryDisplayConfig. It give us all informations that can be viewed in the Configuration Panel of windows.
In particular the PathInfo contains a TargetInfo property that have a targetAvailable flag. This flag seems to be correctly updated on all the configurations I have tried so far.
This allow you to know the state of every screens connected to the PC and set their configurations.
Here a CCD wrapper for .Net
If your monitor has some sort of built-in USB hub, you could try and use that to detect if the monitor is off/on.
This will of course only work if the USB hub doesn't stay connected when the monitor is consider "off".