Почему SendKey.Send () работает только время от времени? - PullRequest
7 голосов
/ 14 сентября 2011

Я делаю приложение для Windows, которое фиксирует ввод с клавиатуры во всем мире.Когда пользователь использует комбинацию клавиш CTRL + ALT + G, приложение использует

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

для ввода генерируемого GUID в любое текстовое поле, находящееся в фокусе.И он должен делать это независимо от приложения, принимающего ввод.

Он работает точно так, как я и задумывал, когда вы в первый раз набираете CTRL + ALT + G, но последующие попытки не приводят ни к чему или просто к очень редким успехам.*

Я имею в виду, все это должно быть очень простым и последовательным.У меня есть работающая глобальная клавиатурная зацепка, которая работает все время, я проверял ее, но метод SendKey.Send () не работает каждый раз.

Я просматривал Google во всем, что связанона мой вопрос, но пока ничего не получалось.

У кого-нибудь есть понимание?

EDIT 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 :

У меня есть еще вопросы по этому вопросу, но у меня нет временипродолжать работать над этим на сегодня.Я реализовал предложение Джона Рейнора об использовании подхода app.config до некоторой степени успеха.Как только я изолирую свои новые проблемы, я опубликую правку и, возможно, закрою этот вопрос, если я получу свое приложение функционирующим как предполагалось.

Ответы [ 2 ]

7 голосов
/ 14 сентября 2011

Возможно, у вас возникли проблемы с синхронизацией. Согласно документации MSDN :

Класс SendKeys был обновлен для .NET Framework 3.0 до включить его использование в приложениях, работающих на Windows Vista. Улучшенный безопасность Windows Vista (известная как контроль учетных записей или UAC) препятствует тому, чтобы предыдущая реализация работала как ожидалось.

Класс SendKeys подвержен ошибкам синхронизации, которые некоторые разработчики должны были обойти. Обновленная реализация все еще подвержены проблемам с синхронизацией, но немного быстрее и может требуют изменений в обходных путях. Класс SendKeys пытается использовать предыдущая реализация в первую очередь, и если это не удается, использует новый реализация. В результате класс SendKeys может вести себя по-разному на разных операционных системах. Кроме того, когда класс SendKeys использует новую реализацию, метод SendWait не будет ждать сообщения, которые будут обработаны, когда они отправлены другому процессу.

Если ваше приложение использует согласованное поведение независимо от операционной системе, вы можете заставить класс SendKeys использовать новый реализации, добавив следующую настройку приложения к вашему файл app.config.

<appSettings> 

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

</appSettings> 

Чтобы заставить класс SendKeys использовать предыдущую реализацию, используйте вместо этого значение "JournalHook".

1 голос
/ 15 сентября 2011

Это не решит вашу конкретную проблему, но является альтернативным подходом.Я экспериментировал с глобальными хуками ключей в управляемом коде раньше.Это боль.Как бы ни был хоккеист и примитив, как бы это ни звучало, я люблю AutoHotKey .С его помощью вы можете сделать несколько действительно мощных вещей.

Вот пример, который удовлетворяет вашему требованию: глобально перехватить Ctrl + Alt + G и набрать guid.Самое приятное, что он компилирует встроенный C #, поэтому вы все равно можете использовать System.Guid.NewGuid().Если у вас есть работающий скрипт, вы можете скомпилировать его в исполняемый файл, чтобы кто-то без установленного 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 , затем загрузитедва дополнительных скрипта здесь и здесь .

...