CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Jun 2005
    Posts
    17

    Question 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

  2. #2
    Join Date
    Jun 2005
    Posts
    17

    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?

  3. #3
    Join Date
    Nov 2003
    Posts
    101

    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.

  4. #4
    Join Date
    Jun 2004
    Location
    NH
    Posts
    678

    Post 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.

  5. #5
    Join Date
    Sep 2000
    Location
    FL
    Posts
    1,452

    Re: Controlling Ctrl + Alt + Del

    Quote 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.

  6. #6
    Join Date
    Jun 2004
    Location
    NH
    Posts
    678

    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

  7. #7
    Join Date
    Jan 2011
    Posts
    4

    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.

  8. #8
    Join Date
    Jan 2006
    Location
    Fox Lake, IL
    Posts
    15,007

    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
    David

    CodeGuru Article: Bound Controls are Evil-VB6
    2013 Samples: MS CODE Samples

    CodeGuru Reviewer
    2006 Dell CSP
    2006, 2007 & 2008 MVP Visual Basic
    If your question has been answered satisfactorily, and it has been helpful, then, please, Rate this Post!

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured