通过直接挂钩发送击键到其他进程 [英] Directly sending keystrokes to another process via hooking

查看:107
本文介绍了通过直接挂钩发送击键到其他进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想知道,所有与SendInput,的SendKeys,PostMessage的,那么SendMessage,SendNotifyMessage,keybd_event,等等等等各种各样的问题,顺藤摸瓜后。为了找到好...试图键盘输入发送到另一个非前台进程是相当挑剔和不可靠的。

我试过,我欺骗的Z顺序(保持当前窗口顶部)和快速前台第三方窗口发送输入,并重新前景我的窗口SendInput的方法。其中最终失败了,也不知怎么的,不知道为什么,管理也PROC我的窗口上的按键,以及虽然没有前景(导致发送和两个窗口之间接收的无限循环,直到我设法关闭进程)。

我试过SendMessage函数和PostMessage的不同组合。一为向下,一个向上,因为同时使用的向下和向上引出的问题,像PostMessage的两个,造成关键重复接收窗口上。或SendMessage函数为,造成问题进行文字输入,但是其他功能工作正常。 SendMessage函数为KeyDown和PostMessage作为KEYUP工作的所有功能,但可靠率急剧下降,以及增加延迟到关键事件。只有PostMessage的,为的keydown为KEYUP结合,SendMessage函数设法做任何有用的事情,有可能5-10%失败KEYUP登记率。同样适用于SentNotifyMessage(以同样的方式作为SendMessage函数主要表现尽可能可靠性云)。

所以基本上,我在圣灵降临节结束的时候,我想知道直接注入钩到目标窗口,并做一些巫术发送击键这种方式,绕过消息队列等。在这样做这样不会PROC全球重要事件,并且只影响目标窗口。唯一的一点是我pretty无知当谈到注入/挂钩等,所以我向你求助,社区。

武汉理工大学办?


解决方案

这是一个小code,使您可以发送短信到后台运行的应用程序。要发送例如A字符,只需调用sendKeystroke(Keys.A),不要忘了使用空间System.Windows.Forms的是能够使用键对象。

 使用系统;
使用System.Collections.Generic;
使用System.Linq的;
使用System.Text;
使用System.Runtime.InteropServices;
使用System.Windows.Forms的;命名空间keybound
{
类WindowHook
{
    函数[DllImport(user32.dll中)]
    公共静态外部的IntPtr FindWindow函数(字符串lpClassName,串lpWindowName);
    函数[DllImport(user32.dll中)]
    公共静态外部的IntPtr SendMessage函数(IntPtr的的HWND,UINT消息,IntPtr的的wParam,lParam的IntPtr的);
    函数[DllImport(user32.dll中)]
    公共静态外部的IntPtr PostMessage的(IntPtr的的HWND,UINT消息,IntPtr的的wParam,lParam的IntPtr的);    公共静态无效sendKeystroke(USHORT K)
    {
        常量UINT WM_KEYDOWN = 0x100的;
        常量UINT WM_SYSCOMMAND =量0x018;
        常量UINT SC_CLOSE = 0x053;        IntPtr的WindowToFind = FindWindow函数(NULL,未命名 - 记事本++);        IntPtr的result3 = SendMessage函数(WindowToFind,WM_KEYDOWN,((IntPtr的)K),(IntPtr的),0);
        // IntPtr的result3 = SendMessage函数(WindowToFind,WM_KEYUP,((IntPtr的)C),(IntPtr的),0);
    }
}
}

I'm wondering, after fiddling with all sorts of issues with SendInput, SendKeys, PostMessage, SendMessage, SendNotifyMessage, keybd_event, etc and so forth. To find that well... trying to send a keyboard input to another non-foreground process is quite finicky and unreliable.

I tried a method of SendInput where I trick the Z-order (to keep the current window on top) and quickly foreground the 3rd party window, send the input, and re-foreground my window. Of which ultimately failed, and also, somehow, not sure why, managed to also proc the keystrokes on my window as well while not foreground (causing an infinite loop of sending and receiving between two windows until I managed to close the process).

I've tried different combinations of SendMessage and PostMessage. One for down, one for up, as using both for down and up leads to issues, like with PostMessage for both, causing the key to duplicate on the receiving window. or SendMessage for both, which caused issues with text entry, but other functions worked ok. SendMessage for keydown and PostMessage for keyUp worked for all functions, but the reliability rate dropped dramatically, as well as adding latency into key events. Only a combination of PostMessage for keydown, and SendMessage for keyup managed to do anything useful, with a maybe 5-10% fail rate of keyup registering. Same goes for SentNotifyMessage (behaves basically in the same fashion as SendMessage as far as reliability goes).

So essentially, I'm at whit's end, and I wanted to know about directly injecting a hook into the target window, and doing some voodoo to send keystrokes to it that way, bypassing the message queue etc. Doing so in a way that will not proc global key events, and only affect the target window. Only thing is I'm pretty unknowledgeable when it comes to injecting/hooking, etc. So I turn to you, community.

Wut do?

解决方案

This is a little code that allows you to send message to a backgrounded application. To send the "A" char for example, simply call sendKeystroke(Keys.A), and don't forget to use namespace System.windows.forms to be able to use the Keys object.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace keybound
{
class WindowHook
{
    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    [DllImport("user32.dll")]
    public static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    [DllImport("user32.dll")]
    public static extern IntPtr PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

    public static void sendKeystroke(ushort k)
    {
        const uint WM_KEYDOWN = 0x100;
        const uint WM_SYSCOMMAND = 0x018;
        const uint SC_CLOSE = 0x053;

        IntPtr WindowToFind = FindWindow(null, "Untitled1 - Notepad++");

        IntPtr result3 = SendMessage(WindowToFind, WM_KEYDOWN, ((IntPtr)k), (IntPtr)0);
        //IntPtr result3 = SendMessage(WindowToFind, WM_KEYUP, ((IntPtr)c), (IntPtr)0);
    }
}
}

这篇关于通过直接挂钩发送击键到其他进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆