Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pressing Win+X, Alt-Tab programmatically

I'm trying to simulate the keypress events for Win+X on Windows 8 which should pop up a small menu, but I have been unable to get this to work by using SendInput. For any other combination of keys (e.g. Win+R, Win+E, Win+D) it works but not for Win+X. I've noticed that Synergy+ has the same problem, but the Windows on-screen keyboard doesn't. I have also looked at the parameters for SendInput that the on-screen keyboard uses but if I use exactly the same parameters in my application I still don't get the menu.

So my question, how do I get this to work? Or is there an alternative way to display this menu?

like image 996
Maurice Gilden Avatar asked Dec 20 '12 12:12

Maurice Gilden


1 Answers

I've recently added support for this to our application. Glad we beat our competitor to it!

There are new UIPI restrictions in Windows 8. The most-used blocked shortcut is Alt+Tab, so you're going to want to do the workaround.

You have to mark your binaries with uiAccess="true" in the manifest. (For more detail on how to do this, google.) This manifest prevents binaries from being launched unless signed with a Microsoft-approved code signing certificate and installed in a "secure location" (system32 or Program Files/Program Files (x86)).

If you lanch your program from any helpers: The uiAccess binary can't be launched with CreateProcess from a medium integrity process (the manifest marks it as requiring "high" integrity). Instead, it's easiest to launch it using ShellExecute "open" to get the shell to elevate it. If using CreateProcessAsUser, you have to set TokenUIAccess to 1 using SetTokenInformation, or launching will fail.

Final provisos: note that uiAccess quite heavily restricts what a process can do. You can't receive UI input from normal (medium integrity) processes, so other applications can't interact with your windows. If you don't already follow good practices in separating your UI into a separate process, this would therefore be a good reason to do that. Alternatively, the tasks requiring uiAccess could be put into a small, self-contained helper binary and entirely separated from the non-UI process too. Your main app can run it as a high-integrity helper process that is sent instructions as required to perform those specific tasks (such as SendInput).

Finally, SendInput will work.

like image 149
Nicholas Wilson Avatar answered Sep 21 '22 02:09

Nicholas Wilson