4

In a C# Console app, pressing the Pause key freezes the display output. Can I disable that?

I was hoping for a handler like the Console.CancelKeyPress event that handles Ctrl+C input.

PeteVasi
  • 723
  • 2
  • 10
  • 23
  • So is it Ctl-C or Pause that you want to trap?? – Sam Axe Mar 30 '12 at 22:01
  • 2
    What on Earth would be the point of this? Uncomfortable about users knowing how to control you instead of you controlling them? You always lose. – Hans Passant Mar 30 '12 at 22:44
  • @HansPassant: Welcome to the land of legacy. There's a WinForms version of the app that already absentmindedly uses Pause/Break. I'm seeing if I can make the console behave the same. – PeteVasi Apr 02 '12 at 13:46

2 Answers2

3

Every once in a while a request comes up for hooking keys from a console program. The standard events like CTRL_C_EVENT and CTRL_CLOSE_EVENT do not include the Pause-event. I've tried doing so using a background thread, but I don't seem to manage. However, there's a not-so-hard workaround: use an extra process.

Download this easy-to-use global keyboard hook for C#. Then, when you open that project, take the following code and put it in the Form1.cs:

public partial class Form1 : Form {

    globalKeyboardHook globalKeyboardHook = new globalKeyboardHook();

    public Form1() {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e) {
        globalKeyboardHook.HookedKeys.Add(Keys.Pause);
        globalKeyboardHook.KeyDown += new KeyEventHandler(globalKeyboardHook_KeyDown);
        globalKeyboardHook.KeyUp += new KeyEventHandler(globalKeyboardHook_KeyUp);
    }

    void globalKeyboardHook_KeyUp(object sender, KeyEventArgs e)
    {
        // remove this when you want to run invisible
        lstLog.Items.Add("Up\t" + e.KeyCode.ToString());

        // this prevents the key from bubbling up in other programs
        e.Handled = true;
    }

    void globalKeyboardHook_KeyDown(object sender, KeyEventArgs e)
    {
        // remove this when you want to run without visible window
        lstLog.Items.Add("Down\t" + e.KeyCode.ToString());

        // this prevents the key from bubbling up in other programs
        e.Handled = true;
    }
}

Then, the rest becomes trivial:

  1. Change your program to start the above program and than run normally
  2. Try to type the pause key
  3. It'll be caught by the other program
  4. Your program will NOT be paused.

I tried the above myself and it works.

PS: I don't mean that there isn't a possible way straight from a Console program. There may very well be, I just didn't find it, and the above global keyhook library didn't work from within a Console application.

Abel
  • 56,041
  • 24
  • 146
  • 247
  • Is there any way to make this hook only swallow Pause key presses from your own console app? – Gabe Mar 30 '12 at 23:20
  • @Gabe: Yes, see the [corresponding MSDN article](http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx). Just specify as ThreadId the id of the main thread of the Console program. This will cause it to _only_ monitor the events of your console app. – Abel Mar 30 '12 at 23:46
  • Will that really work? Since the console app doesn't have a message loop, it's not the process (or thread) that's getting the Pause key messages. I would expect that it's the CSRSS (in Vista and earlier) or conhost (in Win7) that actually contains the message loop thread. – Gabe Mar 31 '12 at 00:10
  • @Gabe: I hoped it would work, but so far I didn't manage myself. The problem is getting the correct ThreadID indeed... Alternatively, you can simply check which program has the input focus. If that's the console app, you can process (i.e., ignore) the Pause key, and in all other cases let it pass. *(PS: looking at other resources with Google gives roughly the same approach as this one: install a system wide hook and take it from there)*. – Abel Mar 31 '12 at 00:12
  • Marked as answer, very clever. I think I'll stick with avoiding the issue though and let the default behavior ride. – PeteVasi Apr 02 '12 at 13:49
0

It's not necessary to attach an hook for this. In your case @PeteVasi, you can modify the console mode to capture Ctrl+C, Ctrl+S, etc... events that are not normally possible to capture.

See my answer to a similar question here.

William R.
  • 145
  • 1
  • 11