为什么 SendKey.Send() 偶尔会起作用?

发布于 2024-12-04 17:55:46 字数 1259 浏览 2 评论 0原文

我正在制作一个捕获全局键盘输入的 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 方法的建议,并取得了一定程度的成功。一旦我隔离了我的新问题,我将发布一个编辑,如果我的应用程序按预期运行,我可能会关闭这个问题。

I'm making a Windows application that captures keyboard input globally. When a user uses the CTRL + ALT + G shortcut combo the application uses

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

to type a generaged GUID into whatever text field is in focus. And it should do this regardless of the application taking the input.

It works exactly as I intended the first time you type CTRL + ALT + G but subsequent attempts result in nothing, or just very infrequent successes.

I mean, it all should be very simple and consistent. I have a working global keyboard hook which works all the time, I've tested it, but the SendKey.Send() method doesn't work every time.

I've looked all over Google at anything related to my issue but nothing has worked so far.

Anyone have any insight?

EDIT 1:
I've tried using SendKey.SendWait() as well, does the same thing. I really want a more responsive way to generate new GUID using this keyboard shortcut approach.

EDIT 2:

Below is the essential parts of the code:

/* 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);

The event code is quite simple:

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

Everything else in my project is just fluff.

Update 1:

I do have more questions about this subject, but I am out of time to continue working on this for today. I have implemented Jon Raynor's suggestion of using the app.config approach to some degree of success. Once I isolate my new problems I'll post an edit and possibly close this question if I get my application functioning as intended.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

久而酒知 2024-12-11 17:55:46

您可能会遇到时间安排问题。根据 MSDN 文档

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

SendKeys 类容易受到计时问题的影响,有些
开发人员不得不想办法解决这个问题。更新后的实现是
仍然容易受到计时问题的影响,但速度稍快一些,并且可能
需要更改解决方法。 SendKeys 类尝试使用
首先使用之前的实现,如果失败,则使用新的
执行。因此,SendKeys 类的行为可能有所不同
在不同的操作系统上。此外,当 SendKeys 类
使用新的实现,SendWait方法将不会等待
消息被发送到另一个进程时要进行处理。

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

; 

<添加键=“SendKeys”值=“SendInput”/> 

 

要强制 SendKeys 类使用以前的实现,请使用
改为值“JournalHook”。

You may be running into timing issues. According to the MSDN documentation:

The SendKeys class has been updated for the .NET Framework 3.0 to
enable its use in applications that run on Windows Vista. The enhanced
security of Windows Vista (known as User Account Control or UAC)
prevents the previous implementation from working as expected.

The SendKeys class is susceptible to timing issues, which some
developers have had to work around. The updated implementation is
still susceptible to timing issues, but is slightly faster and may
require changes to the workarounds. The SendKeys class tries to use
the previous implementation first, and if that fails, uses the new
implementation. As a result, the SendKeys class may behave differently
on different operating systems. Additionally, when the SendKeys class
uses the new implementation, the SendWait method will not wait for
messages to be processed when they are sent to another process.

If your application relies on consistent behavior regardless of the
operating system, you can force the SendKeys class to use the new
implementation by adding the following application setting to your
app.config file.

<appSettings> 

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

</appSettings> 

To force the SendKeys class to use the previous implementation, use
the value "JournalHook" instead.

转角预定愛 2024-12-11 17:55:46

这不会解决您的具体问题,而是一种替代方法。我之前曾在托管代码中尝试过全局键挂钩。很痛苦。尽管听起来很做作和原始,但我喜欢 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 然后下载两个额外的脚本此处此处

This won't address your exact issue, but is an alternative approach. I've experimented with global key hooks in managed code before. It's a pain. As hokey and primitive as it sounds, I love AutoHotKey. You can do some really powerful things with it.

Here's a sample that achieves your requirement of globally hooking Ctrl+Alt+G and typing a guid. The best part is it compiles inline C# so you can still use System.Guid.NewGuid(). Once you have a working script, you can compile it to an exe so someone without AutoHotKey installed can run it.

#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%
}

If you want to try it out, install AutoHotKey_L then download two extra scripts here and here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文