2011-09-14 20 views
7

Estoy haciendo una aplicación de Windows que captura la entrada del teclado de forma global. Cuando un usuario utiliza el acceso directo combinado CTRL + ALT + G la aplicación utiliza¿Por qué SendKey.Send() solo funciona de vez en cuando?

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

para escribir un generaged GUID en cualquier texto campo está en foco. Y debería hacer esto independientemente de la aplicación que tome la entrada.

Funciona exactamente como lo pretendía la primera vez que escribes CTRL + ALT + G, pero los intentos subsiguientes no dan como resultado nada, o solo son éxitos muy poco frecuentes.

Quiero decir, todo debe ser muy simple y consistente. Tengo un gancho de teclado global que funciona todo el tiempo, lo he probado, pero el método SendKey.Send() no funciona todas las veces.

He buscado en Google todo lo relacionado con mi problema pero nada ha funcionado hasta ahora.

¿Alguien tiene alguna idea?

EDITAR 1: He intentado usar SendKey.SendWait() también, hace lo mismo. Realmente quiero una forma más receptiva de generar un nuevo GUID usando este enfoque de atajo de teclado.

EDIT 2:

A continuación se muestra las partes esenciales del código:

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

El código del evento es bastante simple:

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

Todo lo demás en mi proyecto es sólo pelusa.

Actualización 1:

tengo más preguntas sobre este tema, pero estoy fuera de tiempo para seguir trabajando en esto para hoy. He implementado la sugerencia de Jon Raynor de utilizar el enfoque app.config con cierto grado de éxito. Una vez que aísle mis nuevos problemas, publicaré una edición y posiblemente cerraré esta pregunta si logro que mi aplicación funcione según lo previsto.

+0

¿Qué quiere decir con captura de entrada de teclado globalmente? Si lo haces, eso no significa que también recibas el GUID. Seguramente quieres RegisterHotKey. –

+0

Estoy utilizando el pinvoke de RegisterHotKey para este proyecto. Capturar las teclas rápidas es fácil, el problema es con el método SendKey.Send(). – LamdaComplex

+0

Cuando está en su código, ¿llama a SendKey.Send? –

Respuesta

7

Es posible que tenga problemas de sincronización. De acuerdo con la MSDN documentation:

La clase SendKeys se ha actualizado para .NET Framework 3.0 para permitir su uso en aplicaciones que se ejecutan en Windows Vista. La seguridad mejorada de Windows Vista (conocida como Control de cuentas de usuario o UAC) impide que la implementación anterior funcione como se esperaba.

La clase SendKeys es susceptible a problemas de temporización, que algunos desarrolladores de han tenido que solucionar. La implementación actualizada es aún susceptible a problemas de temporización, pero es un poco más rápida y puede requerir cambios en las soluciones provisionales. La clase SendKeys intenta usar primero la implementación anterior, y si eso falla, usa la nueva implementación . Como resultado, la clase SendKeys puede comportarse de manera diferente en diferentes sistemas operativos.Además, cuando la clase SendKeys utiliza la nueva implementación, el método SendWait no esperará a que se procesen los mensajes cuando se envían a otro proceso.

Si su aplicación se basa en un comportamiento coherente, independientemente del sistema operativo , puede forzar a la clase SendKeys para utilizar el nuevo aplicación mediante la adición de la configuración de la aplicación siguiente a su archivo app.config .

<appSettings> 

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

</appSettings> 

Para forzar la clase SendKeys para utilizar la aplicación anterior, use el valor "JournalHook" en su lugar.

+0

Gracias por su respuesta. Sí ayudó a ponerme en la dirección correcta. Aunque esto debería enseñarme a leer la documentación de MSDN con más cuidado. Continúo teniendo problemas con mi aplicación, pero pueden ser el resultado de otros problemas. Si aislo el problema, puedo actualizar esta pregunta. – LamdaComplex

1

Esto no resolverá su problema exacto, pero es un enfoque alternativo. He experimentado con ganchos clave globales en código administrado antes. Es un dolor. Como hokey y primitivo como suena, me encanta AutoHotKey. Puedes hacer cosas realmente poderosas con eso.

Aquí hay una muestra que cumple con su requisito de enganchar globalmente Ctrl + Alt + G y escribir un guid. La mejor parte es que compila C# en línea para que pueda seguir usando System.Guid.NewGuid(). Una vez que tenga un script en funcionamiento, puede compilarlo en un exe para que alguien sin AutoHotKey instalado pueda ejecutarlo.

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

Si quieren probarlo, instale AutoHotKey_L luego descargar dos guiones adicionales y herehere.

+0

Al igual que usted, este experimento hasta ahora no ha traído más que frustración, especialmente teniendo en cuenta lo fácil que DEBERÍA ser. Pero, de nuevo, sé muy poco sobre cómo se implementan los comandos tradicionales de teclas rápidas en Windows. Probaré su solución AutoHotKey y actualizaré esta pregunta pronto. – LamdaComplex

Cuestiones relacionadas