【问题标题】:Get key from any process从任何进程中获取密钥
【发布时间】:2012-12-09 12:07:56
【问题描述】:

我在网上看到了很多解决方案,但没有一个完全符合我的要求。当我的应用程序在后台运行时,在给定进程(不是我的控制台应用程序)中按下任何键的最佳/最简单方法是什么。我不需要修饰符或任何东西。

【问题讨论】:

  • 这叫keylogger,通常不是什么好事
  • @HenkHolterman 你在开玩笑吧?我想用这个键做点什么我想在我的应用程序中捕获它。必须有一个简单的方法来处理窗户把手和东西..
  • 好的,我知道键盘记录​​器是什么,但这不是我想要的。换句话说,我会说。我在玩一个游戏,我必须多次向按钮发送垃圾邮件,这很痛苦,所以我希望一旦按下该按钮,该键会自动按下,直到我释放它。我知道如何完成它我只是不知道如果按下了正确的键如何捕捉
  • 您尝试过其中一种方法吗?它是否满足您的需求,如果是,您为什么不确定使用它?
  • 我发现的几乎所有解决方案都仅限于应用程序本身:(

标签: c# keyboard console-application user32


【解决方案1】:

您要查找的内容称为全局键盘挂钩。您可以找到更多信息和示例on MSDN

【讨论】:

  • 哦,我想这正是我正在寻找的关键字,谢谢!我希望它实施起来不会太难
【解决方案2】:

如果您不特别关心按键被按下的进程,最简单的方法是调用GetAsyncKeyState。虽然它相当有限,因为它不会挂接键盘并且需要您连续调用它。我认为最好的方法是钩住键盘。

使用SetWindowsHookEx,您实际上可以明确指定要与挂钩过程关联的线程的标识符,以便您可以挂钩特定进程的键(请参阅dwThreadId)。

这是一个你可以使用的类(最初是在 Micrsoft 博客上找到的,但我现在似乎找不到作者的名字!)

public delegate IntPtr KeyboardProcess(int nCode, IntPtr wParam, IntPtr lParam);

public sealed class KeyboardHook
{
    public static event EventHandler<KeyPressedEventArgs> KeyPressed;
    private const int WH_KEYBOARD = 13;
    private const int WM_KEYDOWN = 0x0100;
    private static KeyboardProcess keyboardProc = HookCallback;
    private static IntPtr hookID = IntPtr.Zero;

    public static void CreateHook()
    {
        hookID = SetHook(keyboardProc);
    }

    public static void DisposeHook()
    {
        UnhookWindowsHookEx(hookID);
    }

    private static IntPtr SetHook(KeyboardProcess keyboardProc)
    {
        using (Process currentProcess = Process.GetCurrentProcess())
        using (ProcessModule currentProcessModule = currentProcess.MainModule)
        {
            return SetWindowsHookEx(WH_KEYBOARD, keyboardProc, GetModuleHandle(currentProcessModule.ModuleName), 0);
        }
    }

    private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            int vkCode = Marshal.ReadInt32(lParam);

            if (KeyPressed != null)
                KeyPressed(null, new KeyPressedEventArgs((Keys)vkCode));
        }
        return CallNextHookEx(hookID, nCode, wParam, lParam);
    }

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardProcess lpfn, IntPtr hMod, uint dwThreadId);

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

    [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool UnhookWindowsHookEx(IntPtr hhk);

}

public class KeyPressedEventArgs : EventArgs
{
    public Keys KeyCode { get; set; }
    public KeyPressedEventArgs(Keys Key)
    {
        KeyCode = Key;
    }
}

通过控制台应用程序实现:

class Program
{
    static void Main(string[] args)
    {
        KeyboardHook.CreateHook();
        KeyboardHook.KeyPressed += KeyboardHook_KeyPressed;
        Application.Run();
        KeyboardHook.DisposeHook();
    }

    static void KeyboardHook_KeyPressed(object sender, KeyPressedEventArgs e)
    {
        Console.WriteLine(e.KeyCode.ToString());
    }
}

【讨论】:

  • 非常感谢!生病调查它并以结果卷土重来
  • 我正在尝试查找要包含的内容,但我无权访问 KeyPressedEventHandler 或任何 KeyEvents。我怎样才能访问这些课程?
  • 好的,感谢修复工作。对不起,我对此真的很陌生。是的,我有这门课,但我怎样才能从一个进程中访问当前按下的键?
  • 自从阅读您的评论后,我一直在努力让它发挥作用,但一点运气都没有。我认为这样的事情就足够了:var threadID = GetWindowThreadProcessId(FindWindowByCaption(0, "Untitled - Notepad"), IntPtr.Zero); 但显然不是。我查阅了一些关于 SO 的文章,发现这个 post 非常令人望而生畏。
  • 好吧,我知道如何找到我的流程,但我不知道该调用什么以及传递什么。
【解决方案3】:

哦,您是在寻找老式游戏术语中的“自动开火”吗?

与其编写自己的键盘挂钩应用程序(除非您是为了好玩/刺激它/锻炼),您可能想看看 AutoIt 或 AutoHotkey,它们都非常适合键盘/鼠标自动化。

例如查看此线程...http://www.autohotkey.com/board/topic/40598-autofire-keyboard/

【讨论】:

【解决方案4】:

我找到了一种只为进程挂钩的方法。 你可能需要它。

int ProcessId = GetProcessesByName("Your_app_here").FirstOrDefault().Id;
private IntPtr SetHook(KeyboardHookHandler proc)
    {
        return SetWindowsHookEx(13, proc, GetModuleHandle(Process.GetProcessById(ProcessId).MainModule.ModuleName), GetWindowThreadProcessId(GetModuleHandle(Process.GetProcessById(ProcessId).MainModule.ModuleName), out int MainThreadId));
    }

记得导入这些方法。

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr SetWindowsHookEx(int idHook, KeyboardHookHandler lpfn, IntPtr hMod, uint dwThreadId);

[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    private static extern IntPtr GetModuleHandle(string lpModuleName);

[DllImport("user32.dll", SetLastError = true)]
    static extern uint GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-11
    • 2021-07-26
    • 1970-01-01
    相关资源
    最近更新 更多