Envío de un evento de clic del mouse en PowerShell

Envío de un evento de clic del mouse en PowerShell

Al usar Windows PowerShell, habrá solicitudes inusuales que podemos encontrar o no al desarrollar un script para una organización o cliente, y un ejemplo de esto es la grabación y el envío de pulsaciones de teclas. No es adecuado que PowerShell maneje las pulsaciones de teclas, ya que la función es hasta dónde llega la biblioteca de secuencias de comandos, pero es posible ejecutar en PowerShell a pesar de sus limitaciones.

Dado que es un tema complejo, en este artículo nos centraremos más en crear y construir la estructura de entrada de envío y llamar a la clase de clic del mouse de envío en nuestro script.

Use la función de evento del mouse en PowerShell

La función de evento del mouse mouse_event() se deriva de la API Win32 winuser.h, que llama a una API de Microsoft Developer Network (MSDN) específicamente desde la API winuser.h. La API se desarrolló para llamar a una API externa que manejará los eventos del mouse, incluidos los clics del mouse.

Preparemos nuestra variable $cSource para establecer nuestra estructura INPUT e importar todas las bibliotecas que necesitamos para enviar un evento de mouse.

$cSource = @'

using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class Clicker{
[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
    public int 0;
    public MOUSEINPUT mi;
}

//continued on the following script block

Hemos declarado nuestra estructura INPUT, que podemos usar y llamar a una subestructura llamada estructura MOUSEINPUT. Recuerda que el siguiente fragmento todavía está dentro de la clase Clicker.

[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
    public int    dx ;
    public int    dy ;
    public int    mouseData ;
    public int    dwFlags;
    public int    time;
    public IntPtr dwExtraInfo;
}

En algunos casos, habrá ratones avanzados que tienen botones adicionales, pero por ahora, dado que solo nos enfocamos en el clic izquierdo del mouse, podemos declarar las constantes de uso frecuente a continuación. Tenga en cuenta que también hemos declarado una constante para la longitud de pantalla de su monitor.

const int MOUSEEVENTF_MOVED      = 0x0001 ;
const int MOUSEEVENTF_LEFTDOWN   = 0x0002 ;
const int MOUSEEVENTF_LEFTUP     = 0x0004 ;
const int MOUSEEVENTF_RIGHTDOWN  = 0x0008 ;
const int MOUSEEVENTF_RIGHTUP    = 0x0010 ;
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020 ;
const int MOUSEEVENTF_MIDDLEUP   = 0x0040 ;
const int MOUSEEVENTF_WHEEL      = 0x0080 ;
const int MOUSEEVENTF_XDOWN      = 0x0100 ;
const int MOUSEEVENTF_XUP        = 0x0200 ;
const int MOUSEEVENTF_ABSOLUTE   = 0x8000 ;

const int screen_length = 0x10000 ;

Ahora, estamos listos para crear una función que enviará específicamente un evento de clic izquierdo en la pantalla. La función acepta dos argumentos que determinarán la ubicación en el monitor donde ocurrirá el evento de clic izquierdo.

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

public static void LeftClickAtPoint(int x, int y)
{
    //Move the mouse
    INPUT[] input = new INPUT[3];
    input[0].mi.dx = x*(65535/System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width);
    input[0].mi.dy = y*(65535/System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height);
    input[0].mi.dwFlags = MOUSEEVENTF_MOVED | MOUSEEVENTF_ABSOLUTE;
    //Left mouse button down
    input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    //Left mouse button up
    input[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(3, input, Marshal.SizeOf(input[0]));
}
} # Close the Clicker Class
'@ #Close the $cSource variable

Para llamar a nuestra función de clic izquierdo, debemos ensamblar la biblioteca bajo el cmdlet Add-Type. Una vez declarado, ahora podemos llamar a nuestra clase personalizada [Clicker]::LeftClickAtPoint(x,y) para enviar un evento de clic izquierdo del mouse en la pantalla.

Add-Type -TypeDefinition $cSource -ReferencedAssemblies System.Windows.Forms,System.Drawing
[Clicker]::LeftClickAtPoint(300,300)

Guión completo:

$scSource = @'
using System;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;
public class Clicker
{
[StructLayout(LayoutKind.Sequential)]
struct INPUT
{
    public int        type; // 0 = INPUT_MOUSE,
                            // 1 = INPUT_KEYBOARD
                            // 2 = INPUT_HARDWARE
    public MOUSEINPUT mi;
}

[StructLayout(LayoutKind.Sequential)]
struct MOUSEINPUT
{
    public int    dx ;
    public int    dy ;
    public int    mouseData ;
    public int    dwFlags;
    public int    time;
    public IntPtr dwExtraInfo;
}

const int MOUSEEVENTF_MOVED      = 0x0001 ;
const int MOUSEEVENTF_LEFTDOWN   = 0x0002 ;
const int MOUSEEVENTF_LEFTUP     = 0x0004 ;
const int MOUSEEVENTF_RIGHTDOWN  = 0x0008 ;
const int MOUSEEVENTF_RIGHTUP    = 0x0010 ;
const int MOUSEEVENTF_MIDDLEDOWN = 0x0020 ;
const int MOUSEEVENTF_MIDDLEUP   = 0x0040 ;
const int MOUSEEVENTF_WHEEL      = 0x0080 ;
const int MOUSEEVENTF_XDOWN      = 0x0100 ;
const int MOUSEEVENTF_XUP        = 0x0200 ;
const int MOUSEEVENTF_ABSOLUTE   = 0x8000 ;

const int screen_length = 0x10000 ;

[System.Runtime.InteropServices.DllImport("user32.dll")]
extern static uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);

public static void LeftClickAtPoint(int x, int y)
{

    INPUT[] input = new INPUT[3];
    input[0].mi.dx = x*(65535/System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width);
    input[0].mi.dy = y*(65535/System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height);
    input[0].mi.dwFlags = MOUSEEVENTF_MOVED | MOUSEEVENTF_ABSOLUTE;
    input[1].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
    input[2].mi.dwFlags = MOUSEEVENTF_LEFTUP;
    SendInput(3, input, Marshal.SizeOf(input[0]));
}
}
'@
Add-Type -TypeDefinition $scSource -ReferencedAssemblies System.Windows.Forms,System.Drawing
[Clicker]::LeftClickAtPoint(300,300)
Marion Paul Kenneth Mendoza avatar Marion Paul Kenneth Mendoza avatar

Marion specializes in anything Microsoft-related and always tries to work and apply code in an IT infrastructure.

LinkedIn