Before continue reading please note that this article doesn’t intend to call upon you to create nasty applications. If you use this code it should be for your own fun or for learning purposes.
After doing some research on disabling keys or key combinations I found out that there are several ways of achieving the before mentioned key combos. CTRL-ALT-DEL combo is part of the SAS (Secure Attention Sequence) thus the solution to disable this is to write your own gina.dll (Graphical Identification and Authentication).
Don’t worry, I’m not looking into that as for now, I’m going to show you the work around. We will use C#’s Registry editing possibilities to set/change the group policy for the CTRL-ALT-DEL key sequence. Let’s see what we are about to do without programming anything. Open Start Menu > Run and enter gpedig.msc. Navigate to: User Configuration > Administrative Templates > System > CTRL+ALT+DELETE Options.This is the place where you normally set the behaviour of the key combo. Select Remove Task Manager > Double-click the Remove Task Manager option.
If you change it’s value, the following registry entry gets created/modified: Software\Microsoft\Windows\CurrentVersion\Policies\System and the value of DisableTaskMgr gets set to 1.
Now, the task is set. Let’s get down to business and start coding:
Important thing, don’t miss out this line:
using Microsoft.Win32;
And now the method I have created looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public void KillCtrlAltDelete() { RegistryKey regkey; string keyValueInt = "1"; string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"; try { regkey = Registry.CurrentUser.CreateSubKey(subKey); regkey.SetValue("DisableTaskMgr", keyValueInt); regkey.Close(); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } |
If you run the method and try to press CTRL-ALT-DEL the following screen should come up:

So the CTRL-ALT-DEL combo has been taken care of, let’s see the rest. You might have found this a bit difficult, so here’s an easy one. How to disable ALT+F4. 5 lines of code alltogether:
1 2 3 4 5 | private void Form1_FormClosing(object sender, FormClosingEventArgs e) { e.Cancel = true; base.OnClosing(e); } |
Okay. As for the rest I was reading many many articles, and they gave a lot of help. I can’t name one, as I was looking into at least 15 which all held some useful peace of information. I will give you the the source of the method called hooks. The code snippet uses the LowLevelKeyboardProc which is:
The LowLevelKeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was “injected”. However, the WH_KEYBOARD_LL hook is not injected into another process. Instead, the context switches back to the process that installed the hook and it is called in its original context. Then the context switches back to the application that generated the event.
Again, dont forget:
using System.Runtime.InteropServices; using System.Security.Principal; using System.Diagnostics;
Here’s the rest what you need:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | [DllImport("user32", EntryPoint = "SetWindowsHookExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern int SetWindowsHookEx(int idHook, LowLevelKeyboardProcDelegate lpfn, int hMod, int dwThreadId); [DllImport("user32", EntryPoint = "UnhookWindowsHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern int UnhookWindowsHookEx(int hHook); public delegate int LowLevelKeyboardProcDelegate(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam); [DllImport("user32", EntryPoint = "CallNextHookEx", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] public static extern int CallNextHookEx(int hHook, int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam); public const int WH_KEYBOARD_LL = 13; /*code needed to disable start menu*/ [DllImport("user32.dll")] private static extern int FindWindow(string className, string windowText); [DllImport("user32.dll")] private static extern int ShowWindow(int hwnd, int command); private const int SW_HIDE = 0; private const int SW_SHOW = 1; public struct KBDLLHOOKSTRUCT { public int vkCode; public int scanCode; public int flags; public int time; public int dwExtraInfo; } public static int intLLKey; public int LowLevelKeyboardProc(int nCode, int wParam, ref KBDLLHOOKSTRUCT lParam) { bool blnEat = false; switch (wParam) { case 256: case 257: case 260: case 261: //Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key, blnEat = ((lParam.vkCode == 9) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 0)) | ((lParam.vkCode == 91) && (lParam.flags == 1)) | ((lParam.vkCode == 92) && (lParam.flags == 1)) | ((lParam.vkCode == 73) && (lParam.flags == 0)); break; } if (blnEat == true) { return 1; } else { return CallNextHookEx(0, nCode, wParam, ref lParam); } } public void KillStartMenu() { int hwnd = FindWindow("Shell_TrayWnd", ""); ShowWindow(hwnd, SW_HIDE); } private void Form1_Load(object sender, EventArgs e) { intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0); } |
Quite obviously you can programmatically reset these values. Here’s the code to re-enable everything:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public static void ShowStartMenu() { int hwnd = FindWindow("Shell_TrayWnd", ""); ShowWindow(hwnd, SW_SHOW); } public static void EnableCTRLALTDEL() { try { string subKey = "Software\Microsoft\Windows\CurrentVersion\Policies\System"; RegistryKey rk = Registry.CurrentUser; RegistryKey sk1 = rk.OpenSubKey(subKey); if (sk1 != null) rk.DeleteSubKeyTree(subKey); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { UnhookWindowsHookEx(intLLKey); } |
I hope you enjoyed my article and that you found some useful bits. I tried to collect all the information I managed to find during my research on this topic.
February 29th, 2008 at 7:08 pm
Not working for me. Code compiles and runs fine, but it’s not preventing ALT-TAB, CTRL-ALT-DEL, or Windows keys from working. The LowLevelKeyboardProc() method does not seem to get called.
February 29th, 2008 at 8:00 pm
UPDATE: It turns out that it doesn’t work when running through the debugger. But if you compile and run a release version, then it works.
March 1st, 2008 at 2:50 pm
Thanks for your comment. I knew I left something out from the post. The code only works properly through the compiler and not the debugger. Thanks for pointing this out.
March 28th, 2008 at 11:26 am
in LowLevelKeyboardProc function, at:
case 261:
misses following comparison about ALT+F4:
(lParam.vkCode == 115)
Alex from VICENZA(Veneto)
cheers.
April 11th, 2008 at 10:06 am
Given Code is not working. that too “Software\Microsoft\Windows\CurrentVersion\Policies\System” in this given line eacape secuence is wrong.
Please give proper code in NET.
Thanks in advance.
April 23rd, 2008 at 12:09 pm
Hi! thanks for this post of yours.
Question, I’m having an issue on this line..
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
..heres the error.. 211): Method ‘LowLevelKeyboardProc(int, int, ref KBDLLHOOKSTRUCT)’ referenced without parentheses
Can you help me please. Thanks
April 23rd, 2008 at 12:18 pm
Hi JR,
Thanks for your comment. Please double check the method and especially this line:
blnEat = ((lParam.vkCode == 9) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 32)) | ((lParam.vkCode == 27) && (lParam.flags == 0)) | ((lParam.vkCode == 91) && (lParam.flags == 1)) | ((lParam.vkCode == 92) && (lParam.flags == 1)) | ((lParam.vkCode == 73) && (lParam.flags == 0));
(if you copy it from my code it writes amp; insead of the symbol)
instead of the & you should write the actual “and” symbol. Apologies, WP-Syntax is messing things up sometimes.
cheers
May 23rd, 2008 at 10:50 pm
What values do I need to add CTRL + ALT + DEL to the key hook?
May 23rd, 2008 at 11:15 pm
Thanks for your comment Dave. Unfortunately I don’t know which values you need to add to the key hook. I managed “disable” the CTRL - ALT - DEL combo by editing the registry
May 24th, 2008 at 2:50 am
The problem I have noticed with the registry is it only disables using the task manager, but not the actual combination itself. This is a problem for security in some instances. If you find a solution, I will be glad to hear about it. If I find a solution, I will gladly share as well.
May 24th, 2008 at 2:51 am
Also, on Windows Vista, this still leaves the start button a float, but hides the taskbar.
May 27th, 2008 at 11:19 pm
My problem isn’t so much with Ctrl-Alt-Del, but it is related. I have a third party app that decodes streaming video. As soon as I hit Ctrl-Alt-Del, an exception is thrown by the third party app, presumably when the screen goes blank and the Windows Security dialog is displayed. The exception isn’t actually shown until an action is initiated from the Windows Security dialog, but the system event log leads me to believe this. Does anyone know if there is a way to not have the screen go blank and just put the Windows Security dialog on top of the existing apps? I still have a need for the Windows Security dialog. The vendor for the third party app is not being helpful. I won’t mention names. Thanks!
June 2nd, 2008 at 4:58 pm
Raj, try using
âSoftware\\Microsoft\\Windows\\CurrentVersion\\Policies\\Systemâ
so that the first slash acts as an escape sequence.
I have a question/problem.
I have successfully disabled the ctrl-alt-del, alt-tab, etc and I can reenable them on the form closing:
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
ShowStartMenu();
EnableCTRLALTDEL();
UnhookWindowsHookEx(intLLKey);
}
Unfortunately, when the application terminates abnormally (say by a hard reset) all of the ctrl-alt-del, windows key, etc are still disabled when the system starts back up. Is there a way to run a routine (through my application) on system startup to ensure that these controls are enabled? Maybe somehow deleting the subkeytree on system startup?
Thanks.
June 2nd, 2008 at 5:17 pm
Hi John,
Thanks for your comment.
I have just a rough idea, it might work, if you set the application to start with the windows startup, you can add all the enable functions to the from startup process.
@Dave Anderson, thanks for your comment. When I was playing around with this app. Vista was only being release and I haven’t really tested on it
@Wilson: Thanks for your comment as well. What if you tell your application to run above all? O/wise I can’t really help, sorry
June 2nd, 2008 at 6:14 pm
Thanks for the comment Tomaso. To follow up on it:
To set my app to start with windows startup, can I change some settings within my application to do this? Or would I have to change the settings through windows startup options? The reason I’m asking is because I would rather have my application set itself to begin on startup rather than making my clients change the settings after they install my application.
June 2nd, 2008 at 6:30 pm
if you create an installer for your application I remeber that you are able to set your application to startup when windows starts up. I don’t know if you can achieve this when you start your app. up
June 4th, 2008 at 1:22 am
To disable the CTRL-ALT-DEL combination you need to override a function in msgina.dll (does not work on Vista, since file does not exist) as pointed out on top of page.
For me not familiar with c++ or WinAPI, it was hard, but today I finally got it working. When I press the combo the screen just flickers.
If wanted I can present how I solved that part. Now I need some sleep.
Maybe the whole thing is very easy to you.
June 16th, 2008 at 6:12 am
Henrik, if you could post a link to your code, tat would be most helpful.
Thanks!
June 18th, 2008 at 6:43 pm
To use all these together, I have this for my closing event method:
private void EPTTest_FormClosing(object sender, FormClosingEventArgs e)
{
if (this.enableClose == false)
{
e.Cancel = true;
base.OnClosing(e);
}
else
{
UnhookWindowsHookEx(intLLKey);
ShowStartMenu();
EnableCTRLALTDEL();
}
}
To do this, I have a form level variable enableClose initialized to false:
private bool enableClose = false;
And I also have a button that sets the enableClose to true so that alt-f4 is not disabled and so that the application can exit:
private void btnFinish_Click(object sender, EventArgs e)
{
this.enableClose = true;
}
June 18th, 2008 at 9:10 pm
nice one! cheers for your comment!
June 30th, 2008 at 8:47 am
On the debug mode everything works fine, but on the release mode when i try to input something from the keyboard a unhandled exception occurs
June 30th, 2008 at 2:17 pm
The exception is something like that:
CallbackOnCollectedDelegate was detected
Message: A callback was made on a garbage collected delegate of type Form1
July 21st, 2008 at 2:20 pm
Great code. Can you suggest how to remotely connect to the app from another system and ask is to enable the keyboard and gracefully close
Thanks in advance.
July 25th, 2008 at 5:49 am
i’m getting error “Error 1 The type or namespace name ‘FormClosingEventArgs’ could not be found (are you missing a using directive or an assembly reference?) C:\Inetpub\wwwroot\disablekeys\Default.aspx.cs 37 51 C:\…\disablekeys\
”
can u tel me how can i solve this problem????
Shilpa M
August 6th, 2008 at 12:10 am
The code works fine even if it is not the active window. How about disabling the apps key?
August 8th, 2008 at 7:29 am
Really big thanks for your code. But I found that this code:
((lParam.vkCode == 73) && (lParam.flags == 0))
made my textbox control cannot receive character ‘I’. What is the code purpose? To disable windows key?
Please check it, ok.
September 16th, 2008 at 4:26 pm
I’m trying to run this code from a Local System windows service and it doesn’t work. I looked in the registry but the value “DisableTaskMgr” doesn’t appear where it should. When i built a test application and i run it with the User i succeed to disable the task manager and to hide the start menu but i get exceptions thrown when trying to hook the lowlevel keys. i can’t even catch and handle these exceptions since i get the ‘Send/Dont send Error to Microsoft’ message… I’m running Windows XP.
running the win service with a log in other than Local System is NOT a good solution for me. I’ll be glad to hear solutions for both my problems.
Thanks !
September 16th, 2008 at 6:51 pm
thanks guys for the comments.
as I have done this application just for fun I haven’t touched it after.
@Elad, try not to run it in debug mode and if the DisableTaskMgr is not there where it should, rewrite the path.
Also a big sorry cos I have changed the template for my site and for some reason the code is not showing up properly. I’ll try to fix that.
cheers & thanks
October 4th, 2008 at 7:28 am
I writting the above code there are no build error but only ALT+CTRL+DEL can work properly others are not work please help me.
Regards
Sujit Chatterjee
October 7th, 2008 at 4:03 pm
Thanks, for code
but i have some problem :
((lParam.vkCode == 73) && (lParam.flags == 0))
made my textbox control cannot receive character âIâ. What is the code purpose? To disable windows key?
Please reply
October 9th, 2008 at 5:18 am
This semester I have task to build an internet kiosk software. But, I face difficulty to start it. I don’t know how to disable and enable windows key, ctrl+alt+del key, and the alt+tab key.
Is there anyone know how to do that??? I’m using c#.net 2005.
I’ll very appreciate for your help. Thanks
October 20th, 2008 at 5:39 am
i already block ALT+F4 in my c#.net application.
I also need to block ALT+TAB.
So plaese send me the code disable ALT+TAB in c#.net windows application
October 20th, 2008 at 5:40 am
Please give me the code to disable key ALT+TAB in c#.net windows application
October 27th, 2008 at 9:06 am
Just a plain perfect and very comprehensive code. Thank you very much for the code. But just because of the styling some lines are impossible to read. Just with a fix on the styling the page will be flawles.
Again thank you very much.
October 30th, 2008 at 10:54 am
Thanks for the hints and the nice code-snip.
A Problem: When (under VISTA) UAC is ON, it is not possible to write to the registry in HKEY_CURRENT_USER or HKEY_LOCAL_Machine. You do NOT have the necessary access rights.
Any idea anywhere???
Thanks in advance
October 31st, 2008 at 12:52 am
In vista the disable ctrl+alt+del registry can be found in
KEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Group Policy Objects\{237B1F3B-3659-44BE-9965-57EF316DA332}User\Software\Microsoft\Windows\CurrentVersion\Policies\System
but i don’t know if the string between the { } are fixed or no sorry for that i need in that and how can i address this
December 26th, 2008 at 12:02 pm
i have problem that on my Login form i have write code to disable the ALT+F4 Key,
that
e.cancel=true;
but when i write Application.Exit() Method on my Main MDI form, it call my login form at that time i want to close login form, but it not close becoz i write
e.cancel=true on this.
can anyone help me how can i close login form at that time.
thanks in advance
December 26th, 2008 at 5:13 pm
I have the same problem JR had
Hi! thanks for this post of yours.
Question, IĂ¢ĂÂĂÂm having an issue on this line..
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
..heres the error.. 211): Method Ă¢ĂÂĂÂLowLevelKeyboardProc(int, int, ref KBDLLHOOKSTRUCT)Ă¢ĂÂĂ referenced without parentheses
Can you help me please. Thanks
I took the advice in the following comment but still no luck I get the same error can anyone help?
January 13th, 2009 at 12:33 am
I Need code Ctrl+Alt+Detete and Lock key
February 20th, 2009 at 6:13 pm
[...] Burada CTRL+ALT+DEL, Alt+Tab, Alt+Esc, Ctrl+Esc, Windows Key, Start Menu gibi combinasyonlari kapatan bir yazi var okuyabilirsin. sadece CTRL+ALT+DEL i kapatmak icin registry key: SoftwareMicrosoftWindowsCurrentVersionPolicies System de DisableTaskMgr keye 1 degeri vereceksin __________________ ASP.NET MVC sitem Basit bir site ama ASP.NET MVC muhtesem. WebForms u unut! [...]
February 25th, 2009 at 10:15 am
i cant enter any text in my textbox control
if i disable start key
why please help me
March 25th, 2009 at 1:30 pm
i have tried the application released version and i am getting the error as ‘application has a encountered a problem and needs to close. we are sorry for the inconvenience’.
April 9th, 2009 at 6:04 am
Dont work with the CTRL+TAB, ALT+TAB…. Any idea??? some solution about this????
May 1st, 2009 at 5:26 am
It has to disable WinKey-D, WinKey-M, WinKey-L as well
May 1st, 2009 at 6:52 am
See this
http://www.codeproject.com/KB/system/CSLLKeyboard.aspx
May 22nd, 2009 at 3:34 pm
Hey, i am not sure what i am doing wrong, everything runs but none of the commands work :(, in the form load i have:
intLLKey = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, System.Runtime.InteropServices.Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]).ToInt32(), 0);
but it doesn’t seem to work?
If anyone can help me would be great, thanks
May 27th, 2009 at 10:02 pm
can some kind person just compile the code and offer a download link?
July 18th, 2009 at 11:15 pm
there is an error in this code, the type of the reg key have to be DWord and not the standard my code (working) is here
public void killtaskmgr()
{
RegistryKey regkey;
string keyValueInt = “1″;
string subKey = @”Software\Microsoft\Windows\CurrentVersion\Policies\System”;
try
{
regkey = Registry.CurrentUser.CreateSubKey(subKey);
regkey.SetValue(”DisableTaskMgr”, keyValueInt, RegistryValueKind.DWord);
regkey.Close();
}
catch (Exception)
{
}
}
August 1st, 2009 at 9:30 am
… I am using the code but when i push the application with a Flood of
Alt+F4, or ALT+TAB, or Windows Key then it Crashes, any suggestions ?
September 12th, 2009 at 2:32 pm
please post a c++ version!!!
October 3rd, 2009 at 4:29 pm
I couldn’t managed to get it working and i found this, maybe saves somebody 2 hours
cheers
http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/47647b7e-b23f-4f80-9363-ffd5f11a2570
January 12th, 2010 at 6:55 am
Help me, how to disable window key, please help me.
February 10th, 2010 at 7:33 am
Very good and interest article. Thank you.
May 17th, 2010 at 1:09 pm
Hi, hiding “Sart menu” not work under Window 2008. I can hide the start menu, but behind it where is now a bitmap embeded in the taskbar (Shell_TrayWnd) and that tray also send a message to the hidden “start button” and open my start menu.
Seems that MS not want us to disable the start menu in W2008 ?
Regards
Ralf
May 17th, 2010 at 3:43 pm
Hi, how can I disable my start menu in Windows 2008 Server? I hide it but under it there is a bitmap inside “Shell_TrayWnd” and Shell_TrayWnd reacts on clicks and send it to the hiden start menu button and this button popup the menu.
Other idea from a forum: Delete that reg key HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{a2a9545d-a0c2-42b4-9708-a0b2badd77c8} and reboot
seems not work under Windows 2008 R1.
June 1st, 2010 at 9:20 am
Hello
Thanks for code its working fine.
But the problem is when i publish my website on local host it does not work
Pl z reply
July 1st, 2010 at 1:49 pm
Thanks for this code!!!