如何向另一个应用程序发送按键

38

我想向一个名为记事本的程序发送一个特定的按键(例如k),以下是我使用的代码:

private void SendKey()
{
    [DllImport ("User32.dll")]
    static extern int SetForegroundWindow(IntPtr point);

    var p = Process.GetProcessesByName("notepad")[0];
    var pointer = p.Handle;

    SetForegroundWindow(pointer);
    SendKeys.Send("k");
}
            

代码不起作用,代码有什么问题?

我是否可以将“K”发送到记事本而无需记事本成为活动窗口?(例如,活动窗口=“Google Chrome”,记事本在后台运行,这意味着将键发送到后台应用程序)?


1
看看这个是否有帮助:https://dev59.com/n0fRa4cB1Zd3GeqP9Hbm - Zaki
1
它可以工作,但程序所做的是将密钥发送到已经打开的程序,而不是可编程地启动该程序。 - User2012384
调用此方法时记事本是否已经启动? - Antonio Bakula
值得注意的是,dllimport 行是 System.Runtime.InteropServices.DllImport,所以如果没有该绝对路径,您需要为其添加一个使用行,而且我认为这两行 dllimport 行和 extern 行应该放在类之外的方法之外。 - barlop
1
如果您将jandex在https://dev59.com/u3E95IYBdhLWcg3wKq2q#2428108发布的代码添加到您的窗体中,那么您可以向任何处于活动状态的应用程序发送按键消息。您的程序/窗体不会获得焦点,也不会有任何控件获得焦点。 - barlop
显示剩余4条评论
3个回答

71
如果记事本已经启动,你应该写:
// import the function in your class
[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);

//...

Process p = Process.GetProcessesByName("notepad").FirstOrDefault();
if (p != null)
{
    IntPtr h = p.MainWindowHandle;
    SetForegroundWindow(h);
    SendKeys.SendWait("k");
}

GetProcessesByName 返回一个进程数组,因此您应该获取第一个进程(或找到您想要的进程)。

如果您想启动 notepad 并发送键,则应编写:

Process p = Process.Start("notepad.exe");
p.WaitForInputIdle();
IntPtr h = p.MainWindowHandle;
SetForegroundWindow(h);
SendKeys.SendWait("k");

唯一可能导致代码不起作用的情况是当以管理员身份启动记事本时,而你的应用程序没有以管理员身份运行。


但我不想通过编程的方式启动程序,我想做的是向正在运行的程序发送按键,有没有办法实现这个需求? - User2012384
@HugoWong 唯一可能导致代码无法运行的情况是当以管理员身份启动“记事本”而您的应用程序不是。 - Mohammad Dehghan
1
我刚刚读了一篇关于它在Windows 7上并不总是有效的文章,而我正在使用的就是这个系统。有趣的是,它对某些应用程序有效,但却无法将文本转储到我正在尝试的应用程序中。 - Glenn Cuevas
@GlennCuevas请在新问题中描述您的确切情况,我很乐意回答。 - Mohammad Dehghan
@Triynko 我猜可能是出于安全原因,如果一些恶意人士编写了一些恶意代码并启动程序,并在未经用户许可的情况下编写了一些输入,那么这可能是危险的。就像 Android 一样,它们没有 API 来打开/关闭飞行模式,它们只能打开设置,用户必须自己点击。 - User2012384
显示剩余3条评论

0

你可以通过先复制到剪贴板,然后粘贴发送键 ctrl+v 来发送任何内容:

Process p = Process.GetProcessesByName("notepad").FirstOrDefault();

if (p != null)
{
    IntPtr h = p.MainWindowHandle;
    SetForegroundWindow(h);
    Clipboard.Clear();
    Clipboard.SetText(txtCode.Text); 
    string strClip = Clipboard.GetText();
    SendKeys.Send("^{v}");
}

这是剪贴板的原始使用! - S.H.

0
    public string h1;
    public string h2;
    public string m1;
    public string m2;
    public string s1;
    public string s2;

   public partial class Form1 

    hours hour = new hours();
Sendkeys.SendWait(Convert.ToString(hour.h1+hour.h2+hour.m1+hour.m2+hour.s1+hour.s2              +" "));   

只需使用转换为字符串过程将一个类字符串发送到sendkey进程,这是一个简单的问题。


在这个例子中,我创建了一个类字符串序列,它将发送6个字符串到sendkey并添加一个空格。 - Parsidic_thirst
只需使用 Process p = Process.GetProcessesByName("notepad").FirstOrDefault(); 打开程序即可。Mohammad Dehghan 已经说明了。 - Parsidic_thirst

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接