PowerShell에서 마우스 클릭 이벤트 보내기

Marion Paul Kenneth Mendoza 2022년7월12일
PowerShell에서 마우스 클릭 이벤트 보내기

Windows PowerShell을 사용할 때 조직이나 클라이언트를 위한 스크립트를 개발할 때 접할 수도 있고 접하지 않을 수도 있는 비정상적인 요청이 있을 수 있으며, 그 중 하나는 키 입력을 기록하고 보내는 것입니다. 스크립팅 라이브러리가 어디까지 가는 기능인지에 따라 PowerShell에서 키 입력을 처리하는 것은 적합하지 않지만 제한 사항에도 불구하고 PowerShell에서 실행할 수 있습니다.

복잡한 주제이기 때문에 이 기사에서는 보내기 입력 구조를 만들고 구축하고 스크립트에서 보내기 마우스 클릭 클래스를 호출하는 데 더 집중할 것입니다.

PowerShell에서 마우스 이벤트 기능 사용

마우스 이벤트 함수 mouse_event()는 특히 winuser.h API에서 Microsoft 개발자 네트워크(MSDN)의 API를 호출하는 Win32 API winuser.h에서 파생되었습니다. API는 마우스 클릭을 포함하여 마우스 이벤트를 처리할 외부 API를 호출하도록 개발되었습니다.

$cSource 변수를 준비하여 INPUT 구조를 설정하고 마우스 이벤트를 보내는 데 필요한 모든 라이브러리를 가져옵니다.

$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

MOUSEINPUT 구조라는 하위 구조를 사용하고 호출할 수 있는 INPUT 구조를 선언했습니다. 다음 스니펫은 여전히 ​​Clicker 클래스 안에 있습니다.

[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)
{
    //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

왼쪽 클릭 기능을 호출하려면 Add-Type cmdlet 아래에 라이브러리를 어셈블해야 합니다. 일단 선언되면 이제 사용자 정의 클래스 [Clicker]::LeftClickAtPoint(x,y)를 호출하여 화면에서 마우스 왼쪽 클릭 이벤트를 보낼 수 있습니다.

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

전체 스크립트:

$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