nin*_*ite 5 c# vsto office-addins
我正在尝试使用MouseKeyboardActivityMonitor Nugget收听Word AddIn中的键盘输入。当我注册KeyboardHookListener时,我可以接收除Word以外的每个程序上的每个键盘输入。
这可能是某些Word内部保护的原因,还是我缺少了什么?
我有Windows 7 64位和Word 2016 32位。
k_keyListener = new KeyboardHookListener(new GlobalHooker());
k_keyListener.Enabled = true;
k_keyListener.KeyDown += new System.Windows.Forms.KeyEventHandler(hook_OnKeyDown);
public void hook_OnKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
log.Info("Pressed key: " + e.KeyCode.ToString());
}
Run Code Online (Sandbox Code Playgroud)
我不使用Global Hooker,并且我的代码有效。我在Word中对其进行了明确的测试(并且知道它可以在Excel,PowerPoint,Access等环境中工作)。
对于它的价值,微软永远担心Office应用程序被黑客入侵,而您的安全软件可能实际上就是原因。它毕竟是KeyLogger,容易被标记为病毒注入攻击。
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
//enable keyboard intercepts
KeyboardHooking.SetHook();
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
//disable keyboard intercepts
KeyboardHooking.ReleaseHook();
}
}
Run Code Online (Sandbox Code Playgroud)
添加此键盘类:
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace WordAddInKeyHandler
{
class KeyboardHooking
{
[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);
public delegate int LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
//declare the mouse hook constant.
//For other hook types, you can obtain these values from Winuser.h in the Microsoft SDK.
private const int WH_KEYBOARD = 2; // mouse
private const int HC_ACTION = 0;
private const int WH_KEYBOARD_LL = 13; // keyboard
private const int WM_KEYDOWN = 0x0100;
public static void SetHook()
{
// Ignore this compiler warning, as SetWindowsHookEx doesn't work with ManagedThreadId
#pragma warning disable 618
_hookID = SetWindowsHookEx(WH_KEYBOARD, _proc, IntPtr.Zero, (uint)AppDomain.GetCurrentThreadId());
#pragma warning restore 618
}
public static void ReleaseHook()
{
UnhookWindowsHookEx(_hookID);
}
//Note that the custom code goes in this method the rest of the class stays the same.
//It will trap if BOTH keys are pressed down.
private static int HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0)
{
return (int)CallNextHookEx(_hookID, nCode, wParam, lParam);
}
else
{
if (nCode == HC_ACTION)
{
Keys keyData = (Keys)wParam;
// CTRL + SHIFT + 7
if ((BindingFunctions.IsKeyDown(Keys.ControlKey) == true)
&& (BindingFunctions.IsKeyDown(Keys.ShiftKey) == true)
&& (BindingFunctions.IsKeyDown(keyData) == true) && (keyData == Keys.D7))
{
// DO SOMETHING HERE
}
// CTRL + 7
if ((BindingFunctions.IsKeyDown(Keys.ControlKey) == true)
&& (BindingFunctions.IsKeyDown(keyData) == true) && (keyData == Keys.D7))
{
// DO SOMETHING HERE
}
}
return (int)CallNextHookEx(_hookID, nCode, wParam, lParam);
}
}
}
public class BindingFunctions
{
[DllImport("user32.dll")]
static extern short GetKeyState(int nVirtKey);
public static bool IsKeyDown(Keys keys)
{
return (GetKeyState((int)keys) & 0x8000) == 0x8000;
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果有时间,您可以通过比较Global Hooker源代码和我的代码来检查Global Hooker为何不起作用(特别是与Word一起使用)。
在这里引用我的答案:https : //stackoverflow.com/a/10257266/495455也请参阅XNA作者Govert的答案。