0

I'm having a bit of confusion regarding my post here. How to get combination key about 5-10 keys? I'm intended to capture "!qaz$esz" key without double quotes.

My application is a full screen application that prevent access to desktop before entering a right key to enable desktop access. I have kill explorer.exe and disable the Task Manager when the program start and enable it back after combination password is correct:-

private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        /** 
         * 1.   KILL EXPLORER
         * 2.   DISABLE KEY TO TERMINATE
         *      = Alt + F4
         *      = Win + Tab
         *      = Win + D
         *      = etc
         * 3.   ACCEPT SPECIFIC KEY ONLY TO UNLOCK TO MINIMIZE AND SET TOP = FALSE
         * 
         * 
         * **/
        RegistryKey regkey = SetKey(TaskManager.Disabled);
        regkey.Close();
    }
    public static RegistryKey SetKey(TaskManager command)
    {
        RegistryKey mKey;
        string subKey = "Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System";
        mKey = Registry.CurrentUser.CreateSubKey(subKey);
        switch (command)
        {
            case TaskManager.Enabled:
                mKey.SetValue("DisableTaskMgr", 0);
                break;
            case TaskManager.Disabled:
                mKey.SetValue("DisableTaskMgr", 1);
                break;
        }
        return mKey;
    }

But something must be lack on my code where I cannot detect the combination code that more to password.

Below code are what I'm testing to see if my entered key is captured.

 public MainWindow()
    {
        InitializeComponent();
        AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)HandleKeyDownEvent);
    }
    private void HandleKeyDownEvent(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Tab && (Keyboard.Modifiers & (ModifierKeys.Control | ModifierKeys.Shift)) == (ModifierKeys.Control | ModifierKeys.Shift))
        {
            MessageBox.Show("CTRL + SHIFT + TAB trapped"); // Working
        }

        if (e.Key == Key.Tab && (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
        {
            MessageBox.Show("CTRL + TAB trapped"); // Working
        }

        if (e.Key == Key.F4 && Keyboard.Modifiers.HasFlag(ModifierKeys.Alt))
        {
            MessageBox.Show("ALT + F4 trapped"); // Not working
        }
        if (e.Key == Key.D && Keyboard.Modifiers.HasFlag(ModifierKeys.Windows))
        {
            MessageBox.Show("WIN + D trapped"); // Not working
        }
        if ((Keyboard.IsKeyDown(Key.LeftShift) && e.Key == Key.D1) && e.Key ==Key.Q && e.Key == Key.A && e.Key == Key.Z && e.Key == Key.D4 && e.Key == Key.E && e.Key == Key.S && e.Key == Key.Z)
        {
            MessageBox.Show("COMBOKEY"); // Not working
            // RUN EXPLORER
            // ENABLE TASK MANAGER
        }
    }

What is not settle is WINLOGO + D, ALT + TAB, ALT + F4 and LONG COMBINATION KEY.

I have try some of the code from here:-

  1. https://stackoverflow.com/a/5750757/3436326
  2. https://stackoverflow.com/a/17088823/3436326

I have see some discussion/posting/article on writing to LowLevelAPI. I'm not familiar accessing low level API and apply it on WPF application:-

  1. http://www.tamas.io/c-disable-ctrl-alt-del-alt-tab-alt-f4-start-menu-and-so-on/
  2. https://www.codeproject.com/articles/14485/low-level-windows-api-hooks-from-c-to-stop-unwante
Morteza Asadi
  • 1,819
  • 2
  • 22
  • 39
Luiey
  • 843
  • 2
  • 23
  • 50

1 Answers1

1
e.Key == Key.Q && e.Key == Key.A

If e.Key is equal to Key.Q, it cannot be equal to Key.A at the same time. That’s why it’s not working. What you want to detect is the sequence of those keys, and since you only have a key listener, you have to take care of managing the state yourself:

private int passwordState = 0;

private void HandleKeyDownEvent(object sender, KeyEventArgs e)
{
    // other checks

    else if (Keyboard.IsKeyDown(Key.LeftShift) && e.Key == Key.D1)
        passwordState = 1; // first key of the password
    else if (passwordState == 1 && e.Key == Key.Q)
        passwordState = 2;
    else if (passwordState == 2 && e.Key == Key.A)
        passwordState = 3;
    else if (passwordState == 3 && e.Key == Key.Z)
        passwordState = 4;
    else if (passwordState == 4 && e.Key == Key.D4)
        passwordState = 5;
    else if (passwordState == 5 && e.Key == Key.E)
        passwordState = 6;
    else if (passwordState == 6 && e.Key == Key.S)
        passwordState = 7;
    else if (passwordState == 7 && e.Key == Key.Z)
    {
        passwordState = 0;

        // correct password
        MessageBox.Show("COMBOKEY");
    }
    else
        passwordState = 0; // some other/unexpected key: reset password state
}

But that is really annoying to maintain, so why don’t you have a special key combination instead that simply shows a modal prompt for the user to enter the password? Yes, you would show the user a clear password prompt then that they could accidentally discover, but what’s the problem with that?

poke
  • 369,085
  • 72
  • 557
  • 602
  • Hey poke, your suggestion works well. I use your code and got the MessageBox. The things that left is on disabling/preventing/surpress/suspend any combination key that led to program terminate/minimize/switches.. Does I need to access the Low Level API for this? – Luiey Feb 15 '17 at 08:32
  • I’m not too sure about that. Try setting `e.Handled` to `true` so that the event definitely stops propagating. Other than that, I think you will be able to get some more instructions by searching for “kiosk mode” (which is essentially what you are trying to implement here). – poke Feb 15 '17 at 09:20