为什么SendKey.Send()只能偶尔使用一次?

时间:2011-09-14 19:25:10

标签: c# .net keyboard-shortcuts keyboard-events

我正在制作一个全局捕获键盘输入的Windows应用程序。当用户使用CTRL + ALT + G快捷键组合时,应用程序使用

SendKey.Send(Guid.NewGuid().ToString());

将生成的GUID键入到焦点的任何文本字段中。无论应用程序如何输入,都应该这样做。

第一次键入CTRL + ALT + G时,它的工作方式与我的预期完全相同,但后续尝试不会产生任何结果,或者只是非常罕见的成功。

我的意思是,一切都应该非常简单和一致。我有一个工作的全局键盘钩子,它一直工作,我已经测试过,但SendKey.Send()方法每次都不起作用。

我在谷歌的任何与我的问题相关的事情都看了看,但到目前为止还没有任何工作。

任何人都有见解?

编辑1 : 我也尝试过使用SendKey.SendWait(),做同样的事情。我真的想要一种更灵敏的方式来使用这种键盘快捷方式生成新的GUID。

编辑2

以下是代码的基本部分:

/* Initialization Code Here */
// register the event that is fired after the key press.
hook.KeyPressed += new EventHandler<KeyPressedEventArgs>(hook_KeyPressed);
// register the control + alt + F12 combination as hot key.
hook.RegisterHotKey((uint)(HotkeyModifiers.Control | HotkeyModifiers.Alt), Keys.G);

事件代码非常简单:

void hook_KeyPressed(object sender, KeyPressedEventArgs e)
{
    SendKeys.SendWait(Guid.NewGuid().ToString());
}

我项目中的其他所有内容都只是一蹴而就。

更新1

我对此主题有更多疑问,但我没时间继续为此工作。我已经实现了Jon Raynor建议使用app.config方法取得一定程度的成功。一旦我发现我的新问题,我就会发布一个编辑,如果我的应用程序按预期运行,可能会关闭这个问题。

2 个答案:

答案 0 :(得分:7)

您可能遇到计时问题。根据{{​​3}}:

  

已针对.NET Framework 3.0更新了SendKeys类   使其可以在Windows Vista上运行的应用程序中使用。增强   Windows Vista的安全性(称为用户帐户控制或UAC)   阻止先前的实现按预期工作。

     

SendKeys类容易受到时序问题的影响   开发人员不得不解决。更新后的实施是   仍然容易受到计时问题的困扰,但可能会稍快一些   需要更改变通方法。 SendKeys类尝试使用   先前的实现,如果失败,则使用新的   实现。因此,SendKeys类可能表现不同   在不同的操作系统上。另外,当SendKeys类时   使用新的实现,SendWait方法不会等待   将消息发送到另一个进程时要处理的消息。

     

如果您的应用程序依赖于一致的行为而不管   在操作系统中,可以强制SendKeys类使用新的   通过将以下应用程序设置添加到您的实现   app.config文件。

<appSettings> 

<add key="SendKeys" value="SendInput"/> 

</appSettings> 
     

要强制SendKeys类使用以前的实现,请使用   取而代之的是“JournalHook”。

答案 1 :(得分:1)

这不会解决您的确切问题,但是可以采用其他方法。我以前在托管代码中尝试过全局密钥钩子。这是一种痛苦。听起来很古老,我喜欢AutoHotKey。你可以用它做一些非常强大的事情。

这是一个示例,可以满足您全局挂钩Ctrl + Alt + G和输入guid的要求。最好的部分是它编译内联C#,所以你仍然可以使用System.Guid.NewGuid()。一旦你有一个工作脚本,你可以将它编译成一个exe,这样没有安装AutoHotKey的人就可以运行它。

#NoEnv
#SingleInstance
#Include CLR.ahk
#Include COM.ahk

;minimize delay between key presses
SetKeyDelay, -1

;create c# code
CLR_Start()
_g := CLR_CompileC#("class c{public string GetNewGuid(){return System.Guid.NewGuid().ToString();}}", "System.dll").CreateInstance("c")

;hook keyboard ctrl+alt+g
^!g::InsertGuid()

;generate a guid and type it
InsertGuid() {
    global
    local guid := _g.GetNewGuid()
    Send,%guid%
}

如果您想尝试一下,请安装AutoHotKey_L,然后再下载两个额外的脚本herehere