Envoi d'un événement de clic de souris dans PowerShell

Marion Paul Kenneth Mendoza 12 juillet 2022
Envoi d'un événement de clic de souris dans PowerShell

Lors de l’utilisation de Windows PowerShell, il y aura des demandes inhabituelles que nous pouvons ou non rencontrer lors du développement d’un script pour une organisation ou un client, et un exemple de cela est l’enregistrement et l’envoi de frappes. Il n’est pas adapté pour PowerShell de gérer les frappes car la fonction est jusqu’où va la bibliothèque de scripts, mais il est possible de s’exécuter dans PowerShell malgré ses limitations.

Comme il s’agit d’un sujet complexe, dans cet article, nous nous concentrerons davantage sur la création et la construction de la structure d’entrée d’envoi et sur l’appel de la classe d’envoi de clic de souris dans notre script.

Utiliser la fonction d’événement de souris dans PowerShell

La fonction d’événement de souris mouse_event() est dérivée de l’API Win32 winuser.h, qui appelle une API du Microsoft Developer Network (MSDN) spécifiquement à partir de l’API winuser.h. L’API a été développée pour appeler une API externe qui gérera les événements de la souris, y compris les clics de souris.

Préparons notre variable $cSource pour établir notre structure INPUT et importons toutes les bibliothèques dont nous avons besoin pour envoyer un événement de souris.

$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

Nous avons déclaré notre structure INPUT, que nous pouvons utiliser et appeler une sous-structure appelée structure MOUSEINPUT. N’oubliez pas que l’extrait de code suivant est toujours à l’intérieur de la classe Clicker.

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

Dans certains cas, il y aura des souris avancées qui auront des boutons supplémentaires, mais pour l’instant, puisque nous nous concentrons uniquement sur le clic gauche de la souris, nous pouvons déclarer ci-dessous les constantes fréquemment utilisées. Notez que nous avons également déclaré une constante pour la longueur d’écran de votre moniteur.

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 ;

Maintenant, nous sommes prêts à créer une fonction qui enverra spécifiquement un événement de clic gauche sur l’écran. La fonction accepte deux arguments qui détermineront l’emplacement sur le moniteur où l’événement de clic gauche se produira.

[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

Pour appeler notre fonction de clic gauche, nous devons assembler la bibliothèque sous l’applet de commande Add-Type. Une fois déclaré, nous pouvons maintenant appeler notre classe personnalisée [Clicker]::LeftClickAtPoint(x,y) pour envoyer un événement de clic gauche de la souris sur l’écran.

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

Scénario complet :

$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