Prevent hotkey from being lost after a UAC prompt in Windows - c#

BACKGROUND
I wrote an app in C# that registers windows hotkeys (it takes a screenshot when I press PRINTSCREEN)
My code to register the hotkey, capture screen , etc all works. No issues there.
THE PROBLEM
IF my app is running (and successfully has registered the hotkey) and then I do something that causes a UAC prompt - usually this is caused when, for example, I launch some setup program - then the hotkey is lost. Lost = afterwards when I hit printscreen the event never comes back to my app. I have to close the app and restart.
THE QUESTIONS
Why is the hotkey lost?
What can and should I be doing different differently when registering the hotkey?
NOTES
I've seen this behavior with other applications that register hotkeys - running the app with the hotkey using admin privileges prevents the hotkey from being lost
What can and should I be doing different differently when registering the hotkey?
Avoiding apps like setup.exes that cause the UAC prompt is not a viable solution - the entire purpose of my taking screenshots is to document a setup experience over a number of applications
I have a workaround in that I can launch the app with admin rights - but I would rather avoid having to do make users do that
CODE
My code is very similar to this: http://www.codekeep.net/snippets/ea68475b-c33e-4a71-8008-90f63d7e918d.aspx

Given that Print Screen already takes a screenshot and puts it on the clipboard, have you considered monitoring the clipboard for changes instead?
Look at the SetClipboardViewer API function. For example.

When you do something that may cause an UAC - why not unregister the hotkey first and then register it again afterwards?

Related

C# How to send a hotkey globally (needed for a background process, running in system tray)

I am writing a program to automate some work for me.
I have another program (OBS Studio) installed, which I use to capture video. OBS Studio is minimized to the system tray and listens to my configured hotkey CTRL + 1.
When I press CTRL + 1 anywhere, the software starts recording. It does not matter which application is in the foreground.
I am trying to do the same thing from my application, send a "global" hotkey. I have spend hours trying to achieve this, but without any result. SendKeys only works for the current open window (which does not exist), no results with PostMessage either and I tried the wrapper "InputSimulator"
So, to summarize:
Is it possible to send a hotkey/keystroke globally (for every application?)
If not, how would I send a hotkey to a program that is running in the background, without a window? I don't want to bring the app to the foreground.
Hopefully someone with a deeper understanding of these concepts can guide me...
I've found similar questions, but they remain unanswered:
Send global keystroke / fake a global hotkey from a Winforms application
Sources I studied (among others):
https://msdn.microsoft.com/en-us/library/system.windows.forms.sendkeys(v=vs.110).aspx
https://dailyoverdose.wordpress.com/2009/10/28/postmessage-and-sendmessage/
https://ourcodeworld.com/articles/read/520/simulating-keypress-in-the-right-way-using-inputsimulator-with-csharp-in-winforms

How to replace the Logon Application on Windows 10 with a Custom Application

I'd like to make my own custom program run on windows 10 in replacement of the start screen and logon screen.
Is there any way I can do this? I've currently replaced the accessibility program (accessible from the logon screen) with a command prompt, if I accidentally lock myself out (it has happened once!).
I recall seeing a particular Winlogon.exe. Is this my starting point? Am I able to replace the program that windows runs with my own?
Also, wrapping up, If I manage to replace this program, can I logon to windows in my program? I'm writing it in c#.
Old post, but still relevant...
I don't know if you can, or should replace it, but you could write an overlaying app to cover it and do it's own thing, if you can use a little windows command-line magic combined with node.js. More of a work-around, but then you won't chance destroying any os-specific functionality, and it seems to be universal from Vista on up (to my knowledge at least). Here is how you can get your starting point to run a GUI app on the logon screen.
Node-Windows - Run GUI app on Logon screen
You can use this technique to run any app in any language that you can open it's window from a command-line.
There will be a brief period where the normal logon screen will be visible before your app starts, but this will let you do it.
Whatever language you use for your logon GUI, you will need to send simulated key input to the real logon screen, possibly mouse-clicks-- but you can likely use simulated tabs to get to the right logon. Likely MS has API's for C# as well as a variety of related dialects to programmatically logon to the desktop in a more elegant fashion than this last part, however.
Your app will be running as the SYSTEM user (unless you specify otherwise), therefore it will be running with the highest authority-- so you can basically do anything that is possible from there. Permissions won't stop you. Be careful with this.

Disabled CTRL-ALT-DEL, ALT-TAB and Start Menu C# [duplicate]

I'm working on an app (Written in C#) that have a setting to run on KIOSK mode. I've just an challenge here which is disabling Ctrl+Alt+Del combination Event.
There is no right answer in the similar past posts. Please let me know about the right action.
Considering, my code is working with registry keys to disable/enable options, if you know any registry key,it will be more helpful.
CTRL+ALT+DEL is the secure attention sequence of Windows NT (and its derivatives like Win7). It is the one key combination that is guaranteed to get the OS's attention. The whole point of the SAS is that it can't be intercepted or stopped by user programs.
One security issue it addresses is that of a false login screen: consider a screen that looks exactly like the normal Windows login screen. There's no way to tell that it's a fake just by looking at it. But, if you're in the habit of always pressing CTRL+ALT+DEL before logging in (there is an option to always require it for the legitimate screen), pressing the SAS on a false login screen will bring up task manager or the secure attention screen (with the log off, change password, etc options). The real login screen doesn't do that; it just stays there on the screen. As long as the OS itself isn't replaced or compromised, CTRL+ALT+DEL will protect you from false login screens. If a user program could intercept the SAS, it wouldn't be worth anything.
The SAS was baked into the Windows NT design right from the beginning (it was in the first release in 1993), so getting around it won't be easy. I'm sure there are keyboard filter drivers-- or something to intercept that sequence-- that are designed for kiosk use.
It is not possible to capture CTRL+ALT+DEL, it is so by design in all Windows systems. This is a security issue, if the user hits CTRL+ALT+DEL, he or she should be certain that it is the operating system and not some application (possibly a password-catching trojan) that responds to it.
I guess to capture CTRL+ALT+DEL you would need to write a device driver of some sorts.
Edit: Also see This answer. I did not try it, but the question is fairly similar.
Although it is sort of possible, it is not an easy task and not something that can be done in C#. This Article will show you how to disable CTRL+ALT+DEL using group policy editor. To permanently disable the combination though, you will either need to write your own keyboard driver or write your own GINA stub (Graphical Identification and Authentication).
It is possible to pick up the CTRL+ALT+DEL combination, but not to disable it.
I tried to disable it with SetWindowsHookEx and WH_KEYBOARD_LL and you can successfully get notified when CTRL+ALT+DEL is pressed, but you cannot do anything about it.
It is possible to block CTRL+ALT+DEL combination. However, you can't really disable it. As far as I know, there are two possible methods.
Remapping the keyboard layout. There is a registry binary key that allows you to remap keyboard layout:
HKLM\System\CurrentControlSet\Control\Keyboard Layout\Scancode Map
Please check this out: Disabling Windows Hot Keys
This method can be dangerous, but I haven't noticed any side effects this method can cause. The CTRL+ALT+DEL combination is handled by winlogon.exe. If your process has administrative privilege, you can suspend winlogon.exe. Hence, it cannot process the hotkey and nothing will happen if the user presses CTRL+ALT+DEL.
Please check this out: C++ code to disable CTRL+ALT+DEL.
You will need to do some P/Invoke, in user32.dll, there's a method called SystemParametersInfo, check out these resources for more info
http://pinvoke.net/search.aspx?search=SystemParametersInfo&namespace=[All]
http://msdn.microsoft.com/en-us/library/windows/desktop/ms724947%28v=vs.85%29.aspx
I did something similar a long while back, but no longer have the code, though I did find this (it's in vb6), but it shouldn't be too hard to get the idea and translate to .NET
http://www.developerfusion.com/code/1021/how-to-disable-ctrlaltdel/

How to detect and handle external process

I'd like to know with a .net language(C# or VB) if I can detect when a new app is launched.
e.g: an user opens Firefox.exe from desktop (not from my app!), is it possible to detect this event from my app? Also is it possible to "pause" it before running it?
So for example when an user double-clicks an application, my app comes first and then it displays a message if he is sure to open that file with Yes and No buttons.
I don't need all code, I just need to know how to catch that event that can happen anywhere in system.
There are some Windows API functions in user32.dll that you can use in your .NET application through System.Runtime.InteropServices.DllImport to get the information you're looking for. Take a look at GetWindowThreadProcessId. For sample code, see http://www.c-sharpcorner.com/UploadFile/satisharveti/ActiveApplicationWatcher01252007024921AM/ActiveApplicationWatcher.aspx. Because applications tend to become active when they are launched, you'll find that the techniques used in that example will cause it to detect new app launches.
That doesn't answer the question about letting the user confirm whether they want to run an app, but it will get you part of the way towards what you are trying to do.

How can I prevent RegisterHotKey from stopping the default key action?

I'm using the Window's API RegisterHotKey function to run a macro when the F2 key is pressed while a specific application is open and focused.
The problem is, this is stopping the F2 key from working for other applications, such as Excel.
How can I prevent RegisterHotKey from stopping the default action?
I have a system tray application that uses the HotKeyManager class from this answer to register hotkeys. When a specific key is pressed (for example, F2), I use the Windows API to check if a closed-source application is open and focused, and if so send it a series of SendKeys.
From what I understand, you want your global hotkey to work only when one or more selected apps are focused. Can't you simply SendKeys the intercepted strokes if you determine that an incompatible app is in the foreground?
For example,
if (IsSpecificWindowFocused())
{
// Do work
}
else
{
// Resend the key to whatever window is current
SendKeys.Send("{F2}");
}
RegisterHotKey is global, so it is going to trap all of those keystrokes (in other words, I don't believe it is possible to do exactly what you ask).
However, this thread
Global Keyboard Hooks (C#)
talks about creating a keyboard message filter, which is (I believe) more like what you are going for.
To clarify:
RegisterHotKey is going to be best for things like tray apps and anywhere else where you want an OS wide keyboard short cut that doesn't rely on the app being in focus.
Application.AddMessageFilter() is what you want when you want consistent handling of a particular keystroke, but only when your app already has focus.
A way to do what you're describing and still stay in .NET would be to monitor what processes are running on the OS and only enable the global hook when your app is running.

Categories

Resources