-
June 28th, 2005, 03:45 PM
#1
Controlling Ctrl + Alt + Del
I am trying to find a way to capture keyboard events with the intent of preventing users from being able to hit Ctrl + Alt + Del while my application is running. I've spent several hours poking around looking for inspiration but only finding unclear and half-baked examples. As such, I was thrilled to stumble across the article: Managing Low-Level Keyboard Hooks in VB .NET
written by Paul Kimmel (http://www.developer.com/net/vb/article.php/2193301).
This article is insightful, comprehensive, well-written, and I thought it was a huge help. One little problem though, the code that was provided did not work, (I knew it was too good to be true!).
Now, Mr. Kimmel seemed very knowledgable and I think that he probably tested his code, so quite likely the problem is something that I'm doing wrong seeing as I am a newbie. As the article suggests I cut and pasted his code into a module in my project (solution I guess is the proper term), and I call the HookKeyboard method from a button on a form, and Presto! Nothing happens. Stepping through this code I see that the second line in HookKeyboard:
KeyboardHandle = SetWindowsHookEx( _
WH_KEYBOARD_LL, callback, _
Marshal.GetHINSTANCE( _
[Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
is the offending party. After executing this line the value of KeyboardHandle (an integer) is 0 and the value of Err.LastDllError is 127. I have no idea what this means (other than SetWindowsHookEx didn't work) and searching on LastDLLError 127 didn't help much.
Anyone have any ideas why I can't get Paul KImmel's code to work?
Another thing, on the subject of controlling Ctrl + Alt + Del. Anyone know how I would go about forcing Ctrl + Alt + Del programmatically. For example, if I want to mimic the Ctrl + Alt + Del event from the click of a button on a form.
Thanks for taking the time to read my somewhat long winded question and I appreciate whatever feedback you may give.
Adam
-
June 30th, 2005, 06:22 AM
#2
Re: Controlling Ctrl + Alt + Del
OK so I've figured out that forcing Ctrl+Alt+Del programmatically is not possible, as it is a hardware interupt and not something that can be faked. So I've answered part of my own question.
But surely someone out there, some .NET guru, must have something to say on trapping the signal. I know this can be done. As mentioned above Paul Kimmel's article goes into this in some depth, and gives example code that unfortunately dosen't work (at least not the way I'm using it).
Anyone..., anyone at all?
-
June 30th, 2005, 06:27 AM
#3
Re: Controlling Ctrl + Alt + Del
As far as it being impossible to force ctrl+alt+del, I remember using Symantec PC Anywhere a little while back which, if you aren't familiar with the program, allowed you to remotely control another computer. Anyways.. when connected to a remote machine, there was a button that would send a ctrl+alt+del to the remote machine. Not sure how that worked though.
That being said, the whole reason MS uses ctrl+alt+del is because it is a hardware interrupt and impossible or nearly impossible to force/deal with.
-
August 30th, 2005, 06:53 AM
#4
Re: Controlling Ctrl + Alt + Del
One little problem though, the code that was provided did not work
Pleas see my reply for keyboard hooking:
http://www.codeguru.com/forum/showth...light=keyboard
OK so I've figured out that forcing Ctrl+Alt+Del programmatically is not possible
Well that depends on the behavior, you are aiming for and not the definition. For instance starting the task manager is an easy work around. for that behaviour. There is always a way around.
I believe TSmooth is correct, and there is a way to accomplish through a network, if possible for you.
-
August 30th, 2005, 07:54 AM
#5
Re: Controlling Ctrl + Alt + Del
Originally Posted by TSmooth
As far as it being impossible to force ctrl+alt+del, I remember using Symantec PC Anywhere a little while back which, if you aren't familiar with the program, allowed you to remotely control another computer. Anyways.. when connected to a remote machine, there was a button that would send a ctrl+alt+del to the remote machine. Not sure how that worked though.
That being said, the whole reason MS uses ctrl+alt+del is because it is a hardware interrupt and impossible or nearly impossible to force/deal with.
Although it is not VB, you could try downloading the Source code for Ulta-VNC. You can find it at www.ultravnc.com.
In the vncservice.cpp file you will find the code in a function called, "SimulateCtrlAltDel". There are 2 functions you will need and I don't even know if you can convert them to VB.Net however, it will show you the code you need and it does work.
-
September 5th, 2005, 05:19 AM
#6
Controlling Ctrl+Alt+Del Alt+F4 and WinKeys
Code:
Option Strict On
Option Explicit On
Imports System.Threading
Imports System.Reflection
Imports System.Runtime.InteropServices
Public Class Form1
Inherits System.Windows.Forms.Form
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
End Sub
'Form overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
'
'Form1
'
Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Name = "Form1"
Me.Text = "Form1"
End Sub
#End Region
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
HookKeyboard()
apiSystemParametersInfoA(SPI_SETKEYBOARDDELAY, -1, 0, 0)
apiSystemParametersInfoA(SPI_SETKEYBOARDSPEED, 1, 0, 0)
End Sub
Private Sub Form1_Closed(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Closed
UnhookKeyboard()
apiSystemParametersInfoA(SPI_SETKEYBOARDDELAY, 20, 0, 0)
apiSystemParametersInfoA(SPI_SETKEYBOARDSPEED, 20, 0, 0)
End Sub
Public Function IsHooked(ByRef Hookstruct As KBDLLHOOKSTRUCT) As Boolean
On Error Resume Next
' block task manager from the ctrl alt delete combo
If (Hookstruct.vkCode = Keys.Delete OrElse CBool(apiGetAsyncKeyState(Keys.Delete) And &H8000) = True) AndAlso (Hookstruct.vkCode = VK_CONTROL OrElse CBool(apiGetAsyncKeyState(VK_CONTROL) And &H8000) = True) AndAlso (Hookstruct.vkCode = Keys.Menu OrElse CBool(apiGetAsyncKeyState(Keys.Menu) And &H8000) = True) Then Return KillTaskMgr()
'block task manager from the control alt escape combo
If (Hookstruct.vkCode = Keys.Escape OrElse CBool(apiGetAsyncKeyState(Keys.Escape) And &H8000) = True) AndAlso CBool(apiGetAsyncKeyState(VK_CONTROL) And &H8000) AndAlso CBool(apiGetAsyncKeyState(Keys.Shift) And &H8000) Then Return KillTaskMgr()
If (Hookstruct.vkCode = Keys.RWin) Then Return True 'block right win key
If (Hookstruct.vkCode = Keys.LWin) Then Return True 'block left win key
'Block ctrl escape Stops from opening the start menu, as above with win keys.
If CBool(apiGetAsyncKeyState(VK_CONTROL) And &H8000) = True AndAlso Hookstruct.vkCode = Keys.Escape Then Return True
'Block control F4 Stops the closing of a window within an application without closing the main application
If CBool(apiGetAsyncKeyState(VK_CONTROL) And &H8000) = True AndAlso Hookstruct.vkCode = Keys.F4 Then Return True
'Block Alt F4 from directly closing this the application
If CBool(apiGetAsyncKeyState(Keys.Menu) And &H8000) = True AndAlso Hookstruct.vkCode = Keys.F4 Then Return True
'Block Alt Space Stops the opening of the titlebar menu, that can close the alt+f4 combo above
If CBool(apiGetAsyncKeyState(Keys.Menu) And &H8000) = True AndAlso Hookstruct.vkCode = Keys.Space Then Return True
'Stop from switching focus to previous application
If CBool(apiGetAsyncKeyState(Keys.Menu) And &H8000) = True AndAlso Hookstruct.vkCode = Keys.Tab Then Return True
'Stop from switching focus to previous application
If CBool(apiGetAsyncKeyState(Keys.Menu) And &H8000) = True AndAlso Hookstruct.vkCode = Keys.Escape Then Return True
'block any keys you like here, ie a.
' If Hookstruct.vkCode = Keys.A Then Return True
Return False
End Function
Public Function KillTaskMgr() As Boolean
On Error Resume Next
Dim i As Int32
Do
Dim clt() As Process = Process.GetProcessesByName("taskmgr")
For Each p As Process In clt
p.Kill()
Next
Thread.Sleep(1)
i += 1
If i = 200 Then Exit Do 'Set this no larger then the registry's timeout for keyboard hooks. TODO
Loop
End Function
Const VK_CONTROL As Int32 = &H11
Const SPI_SETKEYBOARDDELAY As Int32 = 23
Const SPI_SETKEYBOARDSPEED As Int32 = 11
Public Structure KBDLLHOOKSTRUCT
Public vkCode, scanCode, flags, time, dwExtraInfo As Int32
End Structure
Public Delegate Function KeyboardHookDelegate(ByVal Code As Int32, ByVal wParam As Int32, ByRef lParam As KBDLLHOOKSTRUCT) As Int32
<MarshalAs(UnmanagedType.FunctionPtr)> Private callback As KeyboardHookDelegate
Public KeyboardHandle As Int32
Private Declare Function apiGetAsyncKeyState Lib "user32" Alias "GetAsyncKeyState" (ByVal vKey As Int32) As Int32
Private Declare Function apiSetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As Int32, ByVal lpfn As KeyboardHookDelegate, ByVal hmod As Int32, ByVal dwThreadId As Int32) As Int32
Private Declare Function apiCallNextHookEx Lib "user32" Alias "CallNextHookEx" (ByVal hHook As Int32, ByVal nCode As Int32, ByVal wParam As Int32, ByVal lParam As KBDLLHOOKSTRUCT) As Int32
Private Declare Function apiUnhookWindowsHookEx Lib "user32" Alias "UnhookWindowsHookEx" (ByVal hHook As Int32) As Int32
Private Declare Function apiSystemParametersInfoA Lib "user32" Alias "SystemParametersInfoA" (ByVal uAction As Int32, ByVal uParam As Int32, ByVal lpvParam As Int32, ByVal fuWinIni As Int32) As Int32
Dim clt() As Process = Process.GetProcessesByName("taskmgr")
Public Sub HookKeyboard()
callback = New KeyboardHookDelegate(AddressOf KeyboardCallback)
KeyboardHandle = apiSetWindowsHookEx(13&, callback, Marshal.GetHINSTANCE([Assembly].GetExecutingAssembly.GetModules()(0)).ToInt32, 0)
End Sub
Public Sub UnhookKeyboard()
If Hooked() = True Then Call apiUnhookWindowsHookEx(KeyboardHandle)
End Sub
Private Function Hooked() As Boolean
Return KeyboardHandle <> 0
End Function
Public Function KeyboardCallback(ByVal Code As Int32, ByVal wParam As Int32, ByRef lParam As KBDLLHOOKSTRUCT) As Int32
If (Code = 0) = True AndAlso (IsHooked(lParam)) = True Then Return 1
Return apiCallNextHookEx(KeyboardHandle, Code, wParam, lParam)
End Function
End Class
Last edited by TT(n); May 31st, 2007 at 05:16 AM.
Reason: runs smoother and looks cleaner
-
January 28th, 2011, 03:36 PM
#7
Re: Controlling Ctrl + Alt + Del
Thank you for this, but it doesn't do anything when running on Windows 7. Is there a way to make it work with Windows 7.
I also need to disable any other combos like ctrl+shift+esc that users can use to bypass/close my application.
-
January 28th, 2011, 07:18 PM
#8
Re: Controlling Ctrl + Alt + Del
You need your own version of GINA to do that. You can't block certain sequences from Windows, for good reason
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|