关于键盘监听

we_homder 2008-11-20 12:41:37
请问各位,我想做一个win service程序,放在后台.不停的监听键盘输入.然后把他保存到数据库中.应该如何实现.????谢谢
...全文
835 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
风中暮雨 2011-08-03
  • 打赏
  • 举报
回复
5楼 还是不太理解
olkiuj 2011-03-03
  • 打赏
  • 举报
回复
用SetWindowsHookEx
浮生若梦丶 2008-11-20
  • 打赏
  • 举报
回复
在.NET中并不支持全局的Hook,所以我不建议使用Hook。
你可以通过应用程序一级的消息来得到对按键的处理。比如通过MessageFilter来对应用程序的每一个消息进行处理,可以参考下面的例子不用任何API就可以做到:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace AddMessageFilterApp
{
static class Program
{
class MsgFilter : IMessageFilter
{
public bool PreFilterMessage(ref Message m)
{
if (m.Msg == 0x100 && m.WParam == (IntPtr)0x11) //(WM_RBUTTONDOWN)
{
System.Console.WriteLine(m);
}
else if (m.Msg == 0x100)//WM_KEYDOWN
{
System.Console.WriteLine(m);
}
else if (m.Msg == 0x101)//WM_KEYUP
{
System.Console.WriteLine(m);
}
else if (m.Msg == 102)//WM_CHAR
{
System.Console.WriteLine(m);
}
return false;
}
}

/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
MsgFilter ms=new MsgFilter();
Application.AddMessageFilter(ms);
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
Application.RemoveMessageFilter(ms);
}
}
}

http://hi.baidu.com/xuguoyi/blog/item/c35e3ddd55d376d88c102976.html
CyberKnightGIC 2008-11-20
  • 打赏
  • 举报
回复
监听部分:用p/invoke调用Windows API:
[DllImport("user32.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(
int idHook,
HookProc lpfn,
IntPtr hMod,
int dwThreadId
);

HookProc里面写你的回调函数,
Windows Service很简单拉,创建一个windows service就可以了,最后存数据库就不用说了吧,取得了键盘的keycode存到数据库就行了
wangping_li 2008-11-20
  • 打赏
  • 举报
回复
http://d.download.csdn.net/down/203237/pojianbing
这个也是,我测试过的,可以记录的
我在想的是这记录的都是英文
假如要记录中文怎么办?
wangping_li 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 fly_to_the_winds 的回复:]
在.NET中并不支持全局的Hook,所以我不建议使用Hook。
你可以通过应用程序一级的消息来得到对按键的处理。比如通过MessageFilter来对应用程序的每一个消息进行处理,可以参考下面的例子不用任何API就可以做到:

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace AddMessageFilterApp
{
static class Program
{
class MsgFilter : IMessageFilter
{
public boo…
[/Quote]
谁说的不支持?
楼主可以参考 :
http://download.csdn.net/source/484702
这有一个实例,是将键盘输入的记录到一个文本文件
huwei001982 2008-11-20
  • 打赏
  • 举报
回复
就用 SetWindowsHookEx
we_homder 2008-11-20
  • 打赏
  • 举报
回复
静盼各位的指导.
we_homder 2008-11-20
  • 打赏
  • 举报
回复
homder@sina.com
CyberKnightGIC 2008-11-20
  • 打赏
  • 举报
回复
不需要用不安全代码
bbbbbb888888 2008-11-20
  • 打赏
  • 举报
回复
mark关注
we_homder 2008-11-20
  • 打赏
  • 举报
回复
private void Form1_Load(object sender, System.EventArgs e)
{
// Watch for keyboard activity
KeyboardListener.s_KeyEventHandler += new EventHandler(KeyboardListener_s_KeyEventHandler);
}

private void KeyboardListener_s_KeyEventHandler(object sender, EventArgs e)
{
KeyboardListener.UniversalKeyEventArgs eventArgs = (KeyboardListener.UniversalKeyEventArgs)e;
MessageBox.Show(eventArgs.KeyData.ToString());
}
我是这么写的.运行后.我再键盘上键一个"A" 它为什么会出现两个MessageBox.Show()??
dayizhixiaotutu 2008-11-20
  • 打赏
  • 举报
回复
我有应经写好的service 代码 你邮箱偶发给你
scy251147 2008-11-20
  • 打赏
  • 举报
回复
不懂,帮顶
cpio 2008-11-20
  • 打赏
  • 举报
回复
目前需要用到不安全代码,因为.net不提供这些太底层的访问。
dayizhixiaotutu 2008-11-20
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 we_homder 的回复:]
internal unsafe struct RAWINPUTDEV
{
public ushort usUsagePage;
public ushort usUsage;
public uint dwFlags;
public void* hwndTarget;
};

internal unsafe struct RAWINPUTHEADER
{
public uint dwType;
public uint dwSize;
public void* hDevice;
public void* wParam;
};
//RAWINPUTHEADER  不安全代码 云云
[/Quote]

你把项目的属性 设置下 让他可以运行不安全代码
we_homder 2008-11-20
  • 打赏
  • 举报
回复
internal unsafe struct RAWINPUTDEV
{
public ushort usUsagePage;
public ushort usUsage;
public uint dwFlags;
public void* hwndTarget;
};

internal unsafe struct RAWINPUTHEADER
{
public uint dwType;
public uint dwSize;
public void* hDevice;
public void* wParam;
};
//RAWINPUTHEADER 不安全代码 云云
mjjzg 2008-11-20
  • 打赏
  • 举报
回复
http://www.diybl.com/course/4_webprogram/asp.net/netjs/200832/102539.html
dayizhixiaotutu 2008-11-20
  • 打赏
  • 举报
回复
在service里面跑出个form 窗体 你可以将它隐藏 不让别人看见

然后在form窗体中
private void Form1_Load(object sender, System.EventArgs e)
{
// Watch for keyboard activity
KeyboardListener.s_KeyEventHandler += new EventHandler(KeyboardListener_s_KeyEventHandler);
}

private void KeyboardListener_s_KeyEventHandler(object sender, EventArgs e)
{
KeyboardListener.UniversalKeyEventArgs eventArgs = (KeyboardListener.UniversalKeyEventArgs)e;


这些就是你按下的键的按键信息
“eventArgs.m_Key, eventArgs.m_Msg, eventArgs.KeyData”;
dayizhixiaotutu 2008-11-20
  • 打赏
  • 举报
回复
KbdListener类

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.ComponentModel;

namespace Example
{
/// <summary>
/// The KeyboardListener is a static class that allows registering a number
/// of event handlers that you want to get called in case some keyboard key is pressed
/// or released. The nice thing is that this KeyboardListener is also active in case
/// the parent application is running in the back.
/// </summary>
[System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name="SkipVerification")]
public class KeyboardListener
{
#region Private declarations

/// <summary>
/// The Window that intercepts Keyboard messages
/// </summary>
private static ListeningWindow s_Listener;

#endregion

#region Private methods
/// <summary>
/// The function that will handle all keyboard activity signaled by the ListeningWindow.
/// In this context handling means calling all registered subscribers for every key pressed / released.
/// </summary>
/// <remarks>
/// Inside this method the events could also be fired by calling
/// s_KeyEventHandler(null,new KeyEventArgs(key,msg)) However, in case one of the registered
/// subscribers throws an exception, execution of the non-executed subscribers is cancelled.
/// </remarks>
/// <param name="key"></param>
/// <param name="msg"></param>
private static void KeyHandler(ushort key, uint msg)
{
if(s_KeyEventHandler != null)
{
Delegate[] delegates = s_KeyEventHandler.GetInvocationList();

foreach(Delegate del in delegates)
{
EventHandler sink = (EventHandler)del;

try
{
// This is a static class, therefore null is passed as the object reference
sink(null,new UniversalKeyEventArgs(key,msg));
}

// You can add some meaningful code to this catch block.
catch{};
}
}
}
#endregion

#region Public declarations

/// <summary>
/// An instance of this class is passed when Keyboard events are fired by the KeyboardListener.
/// </summary>
public class UniversalKeyEventArgs : KeyEventArgs
{
public readonly uint m_Msg;
public readonly ushort m_Key;

public UniversalKeyEventArgs(ushort aKey, uint aMsg) : base((Keys)aKey)
{
m_Msg = aMsg;
m_Key = aKey;
}
}

/// <summary>
/// For every application thread that is interested in keyboard events
/// an EventHandler can be added to this variable
/// </summary>
public static event EventHandler s_KeyEventHandler;

#endregion

#region Public methods

static KeyboardListener()
{
ListeningWindow.KeyDelegate aKeyDelegate = new ListeningWindow.KeyDelegate(KeyHandler);
s_Listener = new ListeningWindow(aKeyDelegate);
}

#endregion

#region Definition ListeningWindow class
/// <summary>
/// A ListeningWindow object is a Window that intercepts Keyboard events.
/// </summary>
private class ListeningWindow : NativeWindow
{
#region Declarations
public delegate void KeyDelegate( ushort key, uint msg );

private const int
WS_CLIPCHILDREN = 0x02000000,
WM_INPUT = 0x00FF,
RIDEV_INPUTSINK = 0x00000100,
RID_INPUT = 0x10000003,
RIM_TYPEKEYBOARD = 1;

private uint m_PrevMessage = 0;
private ushort m_PrevControlKey = 0;
private KeyDelegate m_KeyHandler = null;
#endregion

#region Unsafe types
internal unsafe struct RAWINPUTDEV
{
public ushort usUsagePage;
public ushort usUsage;
public uint dwFlags;
public void* hwndTarget;
};

internal unsafe struct RAWINPUTHEADER
{
public uint dwType;
public uint dwSize;
public void* hDevice;
public void* wParam;
};

internal unsafe struct RAWINPUTHKEYBOARD
{
public RAWINPUTHEADER header;
public ushort MakeCode;
public ushort Flags;
public ushort Reserved;
public ushort VKey;
public uint Message;
public uint ExtraInformation;

};
#endregion

public ListeningWindow(KeyDelegate keyHandlerFunction)
{
m_KeyHandler = keyHandlerFunction;

CreateParams cp = new CreateParams();

// Fill in the CreateParams details.
cp.Caption = "Hidden window";
cp.ClassName = null;
cp.X = 0x7FFFFFFF;
cp.Y = 0x7FFFFFFF;
cp.Height = 0;
cp.Width = 0;
//cp.Parent = parent.Handle;
cp.Style = WS_CLIPCHILDREN;

// Create the actual invisible window
this.CreateHandle(cp);

// Register for Keyboard notification
unsafe
{
try
{
RAWINPUTDEV myRawDevice = new RAWINPUTDEV();
myRawDevice.usUsagePage = 0x01;
myRawDevice.usUsage = 0x06;
myRawDevice.dwFlags = RIDEV_INPUTSINK;
myRawDevice.hwndTarget = this.Handle.ToPointer();

if (RegisterRawInputDevices(&myRawDevice, 1, (uint)sizeof(RAWINPUTDEV)) == false)
{
int err = Marshal.GetLastWin32Error();
throw new Win32Exception(err,"ListeningWindow::RegisterRawInputDevices");
}
}

catch {throw;}
}
}


#region Private methods
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_INPUT:
{
try
{
unsafe
{
uint dwSize, receivedBytes;
uint sizeof_RAWINPUTHEADER = (uint)(sizeof(RAWINPUTHEADER));

// Find out the size of the buffer we have to provide
int res = GetRawInputData(m.LParam.ToPointer(), RID_INPUT, null, &dwSize, sizeof_RAWINPUTHEADER);

if(res == 0)
{
// Allocate a buffer and ...
byte* lpb = stackalloc byte[(int)dwSize];

// ... get the data
receivedBytes = (uint)GetRawInputData((RAWINPUTHKEYBOARD*)(m.LParam.ToPointer()), RID_INPUT, lpb, &dwSize, sizeof_RAWINPUTHEADER);
if ( receivedBytes == dwSize )
{
RAWINPUTHKEYBOARD* keybData = (RAWINPUTHKEYBOARD*)lpb;

// Finally, analyze the data
if(keybData->header.dwType == RIM_TYPEKEYBOARD)
{
if((m_PrevControlKey != keybData->VKey) || (m_PrevMessage != keybData->Message))
{
m_PrevControlKey = keybData->VKey;
m_PrevMessage = keybData->Message;

// Call the delegate in case data satisfies
m_KeyHandler(keybData->VKey,keybData->Message);
}
}
}
else
{
string errMsg = string.Format("WndProc::GetRawInputData (2) received {0} bytes while expected {1} bytes", receivedBytes, dwSize);
throw new Exception(errMsg);
}
}
else
{
string errMsg = string.Format("WndProc::GetRawInputData (1) returned non zero value ({0})", res);
throw new Exception(errMsg);
}
}
}

catch {throw;}
}
break;
}

// In case you forget this you will run into problems
base.WndProc(ref m);
}

#endregion

#region Private external methods

[DllImport("User32.dll",CharSet = CharSet.Ansi,SetLastError=true)]
[return : MarshalAs(UnmanagedType.Bool)]
internal static extern unsafe bool RegisterRawInputDevices( RAWINPUTDEV* rawInputDevices, uint numDevices, uint size);

[DllImport("User32.dll",CharSet = CharSet.Ansi,SetLastError=true)]
[return : MarshalAs(UnmanagedType.I4)]
internal static extern unsafe int GetRawInputData( void* hRawInput,
uint uiCommand,
byte* pData,
uint* pcbSize,
uint cbSizeHeader
);

#endregion
}
#endregion
}
}

加载更多回复(2)

111,130

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧