Simular Key Press !!

Iniciado por TrashAmbishion, 21 Junio 2016, 07:39 AM

0 Miembros y 1 Visitante están viendo este tema.

TrashAmbishion

He probado varios codigos de la RED incluso el de Electro y no me funciona necesito simular que presiono la tecla F10, alguna idea mi sistema es Windows 8.1.

Codigo de Elektro

http://foro.elhacker.net/buscador-t413217.0.html

Probe este otro y nada

http://www.visual-basic-tutorials.com/223201022306.php

Es para hacer una captura de pantalla con el programa FRAP

Eleкtro

#1
Cita de: TrashAmbishion en 21 Junio 2016, 07:39 AM
He probado varios codigos de la RED incluso el de Electro y no me funciona necesito simular que presiono la tecla F10, alguna idea mi sistema es Windows 8.1.

Codigo de Elektro

http://foro.elhacker.net/buscador-t413217.0.html

Hola.

El código que has citado no sirve para sintetizar pulsaciones de teclado, sino para enviar caracteres, por ende, no es posible utilizar las teclas especiales Fn. Aparte de eso, no está demasiado bien enfocada la implementación de los métodos, me refiero, la función que escribí se debería haber llamado SendChar en lugar de SendKey para evitar este tipo de confusión.

Para enviar pulsaciones del teclado la metodología es practicamente idéntica, solo que obviamente no hay que realizar ninguna conversión a caracter. Puedes tratar de modificar el código que publiqué para ignorar la conversión a caracter a ver si así funciona como esperas.

Te mostraría un ejemplo actualizado y completo pero son bastantes definiciones las que hay que usar y agrandaría demasiado (todavía más) esta respuesta, sin embargo, todo lo que necesitas lo puedes encontrar en la implementación que hice de RAW_INPUT en mi API ElektroKit, solo tienes que copiar y pegar los miembros relacionados entre sí:

Código (vbnet) [Seleccionar]

       <SuppressUnmanagedCodeSecurity>
       <DllImport("user32.dll", SetLastError:=True)>
       Public Shared Function SendInput(ByVal nInputs As Integer,
<MarshalAs(UnmanagedType.LPArray), [In]> ByVal pInputs As Input32(),
                                        ByVal cbSize As Integer
       ) As Integer
       End Function

       <SuppressUnmanagedCodeSecurity>
       <DllImport("user32.dll", SetLastError:=True)>
       Public Shared Function SendInput(ByVal nInputs As Integer,
<MarshalAs(UnmanagedType.LPArray), [In]> ByVal pInputs As Input64(),
                                        ByVal cbSize As Integer
       ) As Integer
       End Function


+

( click en las imágenes para ir al código fuente )





( Además de las estructuras mencionadas, también necesitarás: Win32.Types.InputType, Win32.Types.MouseInput, Win32.Types.KeyboardInput y Win32.Types.HardwareInput )

+



 (Función: Keyboard.SendKey())

Nota:
La estructura Input está dividida en dos, una para ser utilizada bajo Windows x86, y la otra para Windows x64. Y a raíz de lo mencionado hay una condicional para utilizar una estructura o la otra en el bloque del método SendKey (entre otros). El motivo de todo esto es que en un principio se me dificultó la tarea de portabilizar la estructura, sin embargo, todo eso ya lo refactoricé y lo simplifiqué, pero el código que hay publicado en GitHub está desactualizado (de todas formas te funcionará correctamente. simplemente es un código feo o guarro por así decirlo).




Si te parece mucho lio todo lo de arriba, la alternativa sería compilar la librería y/o descargar la última release ya compilada desde GitHub, y entonces simplemente tienes que llamar a la función Elektro.Core.IO.Tools.Keyboard.SendKey().

Ejemplo de uso:
Código (vbnet) [Seleccionar]
Imports Elektro.Core.IO.Enums
Imports Elektro.Core.IO.Tools

Public NotInheritable Class Form1

   Private Sub Button1_Click() Handles Button1.Click

       Process.Start("proceso.exe")
       Thread.Sleep(TimeSpan.FromSeconds(5))
       Keyboard.SendKey(Keys.F10, KeyBehavior.Press)

   End Sub

End Class


Saludos








TrashAmbishion

Que tal Elektro gracias por tu pronta respuesta, bueno no estaba muy familiarizado con el GitHub ya (gracias a ti) toy un poco mas actualizado con el.

Bueno tome el ultimo ejemplo que pusistes y en esta linea

Código (vbnet) [Seleccionar]

         Keyboard.SendKey(Keys.F10, KeyBehavior.Press)


El KeyBehavior me lo sigue marcando como que no lo reconoce y para colmo perdi tu CHM mañana lo descargo.

okik

#3
hola

MODO 1

USANDO SENDINPUT

Código (vbnet) [Seleccionar]

Imports System.Security
Imports System.Runtime.InteropServices
Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       Dim sInput As NativeMethods.INPUT
       sInput.type = NativeMethods.INPUT_KEYBOARD
       sInput.ki.wVk = Keys.F10
       sInput.ki.dwFlags = 0

       NativeMethods.SendInput(1, sInput, Marshal.SizeOf(GetType(NativeMethods.INPUT)))
   End Sub
End Class


<SuppressUnmanagedCodeSecurity()>
Friend NotInheritable Class NativeMethods
   Private Sub New()
   End Sub

   <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
   Friend Shared Function SendInput(ByVal cInputs As Integer, ByRef pInputs As INPUT, ByVal cbSize As Integer) As Integer
   End Function

   Structure MOUSEINPUT
       Public dx As Integer
       Public dy As Integer
       Public mouseData As Integer
       Public dwFlags As Integer
       Public time As Integer
       Public dwExtraInfo As IntPtr
   End Structure

   Structure KEYBDINPUT
       Public wVk As Short
       Public wScan As Short
       Public dwFlags As Integer
       Public time As Integer
       Public dwExtraInfo As IntPtr
   End Structure
   Structure HARDWAREINPUT
       Public uMsg As Integer
       Public wParamL As Short
       Public wParamH As Short
   End Structure

   <StructLayout(LayoutKind.Explicit)> _
   Structure INPUT
       <FieldOffset(0)> _
       Public type As Integer
       <FieldOffset(4)> _
       Public mi As MOUSEINPUT
       <FieldOffset(4)> _
       Public ki As KEYBDINPUT
       <FieldOffset(4)> _
       Public hi As HARDWAREINPUT
   End Structure


   Public Const VK_H As Short = 72
   Public Const VK_E As Short = 69
   Public Const VK_L As Short = 76
   Public Const VK_O As Short = 79

   Public Const KEYEVENTF_KEYUP As Integer = &H2
   Public Const INPUT_MOUSE As Integer = 0
   Public Const INPUT_KEYBOARD As Integer = 1
   Public Const INPUT_HARDWARE As Integer = 2


End Class






MODO 2

USANDO KEYBD_EVENT

Código (vbnet) [Seleccionar]

Imports System.Security
Imports System.Runtime.InteropServices

Public Class Form1

   Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       NativeMethods.keybd_event(Keys.F10, 0, 0, 0)
       NativeMethods.keybd_event(Keys.F10, 0, NativeMethods.KeyEventFlags.KEYEVENTF_KEYUP, 0)
   End Sub
End Class

<SuppressUnmanagedCodeSecurity()>
Friend NotInheritable Class NativeMethods
   Private Sub New()
   End Sub

   <DllImport("user32.dll", CharSet:=CharSet.Auto)> _
   Friend Shared Sub keybd_event(ByVal bVk As Byte, _
       ByVal bScan As Byte, _
       ByVal dwFlags As Integer, _
       ByVal dwExtraInfo As Integer)
   End Sub

   <Flags()> _
   Public Enum KeyEventFlags As UInteger
       VK_NUMLOCK = &H90
       VK_SCROLL = &H91
       VK_CAPITAL = &H14
       KEYEVENTF_EXTENDEDKEY = &H1
       KEYEVENTF_KEYUP = &H2
       VER_PLATFORM_WIN32_NT = 2
       VER_PLATFORM_WIN32_WINDOWS = 1
   End Enum
End Class




Por ahí hay gente que aconseja usar SendInput, pero funciona en los dos casos. Por lo menos en mi OS, en el tuyo no se. Ambos usan User32.dll.

Eleкtro

#4
@okik

Hola.

Cita de: okik en 22 Junio 2016, 02:30 AMPor ahí hay gente que aconseja usar SendInput

El problema con la función keybd_event, aparte de la limitada versatilidad que proporciona en comparación, es que está considerada obsoleta. Es una función muy, muy antigua, y esto significa que en cualquier momento podría desaparecer en la API de futuras versiones de Windows, y por ende, volverse incompatible con ciertas aplicaciones que sigan usando esta metodología (como ha ido sucediendo a lo largo de los años con otras funciones consideradas obsoletas).




Cita de: okik en 22 Junio 2016, 02:30 AMfunciona en los dos casos.

En realidad no, la definición que has compartido de SendInput solo funcionará bajo Windows/proceso de 32 Bits. No funcionará en Windows/proceso de 64 Bits.

La alineación de offsets que has definido es incorrecta, puesto que en Windows de 64 Bits la unión de miembros empezará en el byte 8, no 4.
Si usas la funcionalidad CA (Code Analysis) de Visual Studio, te advertirá de este problema diciéndote que los miembros de la estructura Input no son portables. O también puedes compilar el código bajo x64 (no AnyCPU/Preffer 32Bit) para comprobar que efectivamente no funciona, no se sintetizan las pulsaciones.

La solución a este problema es muy sencilla, simplemente los miembros de la estructura SendInput deben ser declarados de forma secuencial, no explícita. Aparte, debes mover las estructuras MOUSEINPUT, KEYBDINPUT, HARDWAREINPUT a una estructura diferente y entonces sí, alinear las posiciones de la unión de miembros de forma explícita.

Con el código que actualmente has compartido, esta sería la solución para portabilizar tu estructura Input:

Código (vbnet) [Seleccionar]
   <StructLayout(LayoutKind.Sequential)>
   Structure Input
       Public Type As Integer
       Public Info As InputInfo
   End Structure

   <StructLayout(LayoutKind.Explicit)>
   Structure InputInfo
       <FieldOffset(0)>
       Public Mi As MOUSEINPUT
       <FieldOffset(0)>
       Public Ki As KEYBDINPUT
       <FieldOffset(0)>
       Public Hi As HARDWAREINPUT
   End Structure

   <StructLayout(LayoutKind.Sequential)>
   Structure MouseInput
       ' ...
   End Structure

   <StructLayout(LayoutKind.Sequential)>
   Structure KeyboardInput
       ' ...
   End Structure

   <StructLayout(LayoutKind.Sequential)>
   Structure HardwareInput
       ' ...
   End Structure


Saludos








TrashAmbishion

Dios jajajaja  :o :o :o :o

Embullate da clases online... GGG

Bueno entre tanto y tanto el Metodo 2 me funciono no obstante probare el 1ero con los ajustes y comento.

PD: Mas me interesa poder hacer la captura de la imagen del juego sin necesidad de usar un programa externo que me haga esto, es el objetivo de este codigo. Que ya estoy cerca de resolver.

Salu2 y Graciasss