【问题标题】:Get Keyboard input for Word process in VSTO AddIn在 VSTO 插件中获取 Word 进程的键盘输入
【发布时间】:2019-08-22 08:01:25
【问题描述】:

我正在尝试使用 MouseKeyboardActivityMonitor Nugget 在我的 Word 插件中收听键盘输入。当我注册 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());
}

【问题讨论】:

    标签: c# vsto office-addins


    【解决方案1】:

    我不使用 Global Hooker,我的代码可以正常工作。我在 Word 中明确测试过它(并且知道它可以在 Excel、PowerPoint、Access 等中使用)。

    不管怎样,Microsoft 一直担心 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();
        }
    }
    

    添加这个键盘类:

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

    如果您有时间,您可以通过将 Global Hooker 源代码与我的源代码进行比较来检查 Global Hooker 无法正常工作的原因(特别是使用 Word)。

    在此处参考我的答案:https://stackoverflow.com/a/10257266/495455 另请参阅 XNA 的作者 Govert 的答案。

    【讨论】:

      猜你喜欢
      • 2015-04-13
      • 2013-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-28
      • 2022-01-22
      相关资源
      最近更新 更多