我正在制作一个全局捕获键盘输入的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方法取得一定程度的成功。一旦我发现我的新问题,我就会发布一个编辑,如果我的应用程序按预期运行,可能会关闭这个问题。
答案 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,然后再下载两个额外的脚本here和here。