Default Blue Green Red
Pages: [1]
  Print  
Author Topic: CConsoleHook (C#)  (Read 344 times)
BC_Programming
Administrator
Newbie
*

Total Thanks: 0
Offline Offline

Posts: 22



View Profile Email
« on: March 31, 2010, 08:36:13 AM »

Amazingly, C# doesn't give programmers the ability to hook such things as Control+C or Control Break, or when your console application is closed via log off, or whatever.

I'm rather Noobish to C# but it seemed like a doable challenge, and I've written similar features for VB6.

I'm proud to say it was a success! Here is the Class:

Code: (csharp)

using System;
using System.Runtime.InteropServices;
namespace ConsoleHook
{
    
    public enum ConsoleEventConstants
    {
        CTRL_C_EVENT = 0,
        CTRL_BREAK_EVENT = 1,
        CTRL_CLOSE_EVENT = 2,
        CTRL_LOGOFF_EVENT = 5,
        CTRL_SHUTDOWN_EVENT = 6

    }
    public delegate int HandlerRoutine(ConsoleEventConstants ConsoleEvent);
    public class CConsoleHook : IDisposable
    {


        private HandlerRoutine mHandler;
        [DllImport("kernel32.dll")]
        private static extern int SetConsoleCtrlHandler(Delegate HandlerRout, int Add);
        public CConsoleHook(HandlerRoutine handler)
        {
            mHandler = handler;
            //add it to the Control handler...
            SetConsoleCtrlHandler(new HandlerRoutine(innerhandler), 1);
        }
        ~CConsoleHook()
        {
            this.Dispose();
        }
        public void Dispose()
        {
            if (mHandler != null)
            {
                SetConsoleCtrlHandler(mHandler, 0);
            }
        }
        private int innerhandler(ConsoleEventConstants ConsoleEvent)
        {
            if (mHandler != null)
            {
                return mHandler(ConsoleEvent);
            }
            else
            {
                return 0;
            }
        }


    }
}


My original concept placed this in it's own ConsoleHook library (thus the namespace declaration) there is, of course, nothing stopping anybody from simply plopping it into the same project that they want to use it in. (Not sure how namespace directives get along in the same project, but it will probably work.

The test application was a simple C# Console program:

Code: (csharp)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ConsoleHook;
namespace testconhook
{
    class Program
    {
        private static CConsoleHook conhook;
        static void Main(string[] args)
        {
            conhook = new CConsoleHook(new HandlerRoutine(handler));

            while (true)
            {
                String s = System.Console.ReadLine();
            }
        }
        static int handler(ConsoleHook.ConsoleEventConstants param)
        {
            //System.Windows.Forms.MessageBox.Show("ConsoleEvent Constants called with:" + param);
            System.Console.WriteLine("ConsoleEvent Called :" + param);
            return 1;

        }
    }
}



This is a rather basic demonstration. Actually, it highlight a feature that I didn't know about but still think is awesome (and probably exists in VB.NET as well)... enumerated types are printed as their name, rather then just as their value.


EDIT: Almost forgot! I really have to give "props" to APIViewer 2004, which I have been using for as long as I remember for API declarations for Visual Basic 6. It can provide declarations in a number of languages, including C#, Delphi, powerBASIC, etc. Best of all it's free!
« Last Edit: March 31, 2010, 08:40:27 AM by BC_Programming » Logged

Pages: [1]
  Print  
 
Jump to: