power shell : how to send middle mouse click?

18,107

Solution 1

function Click-MouseButton
{
param(
[string]$Button, 
[switch]$help)
$HelpInfo = @'

Function : Click-MouseButton
By       : John Bartels
Date     : 12/16/2012 
Purpose  : Clicks the Specified Mouse Button
Usage    : Click-MouseButton [-Help][-Button x]
           where      
                  -Help         displays this help
                  -Button       specify the Button You Wish to Click {left, middle, right}

'@ 

if ($help -or (!$Button))
{
    write-host $HelpInfo
    return
}
else
{
    $signature=@' 
      [DllImport("user32.dll",CharSet=CharSet.Auto, CallingConvention=CallingConvention.StdCall)]
      public static extern void mouse_event(long dwFlags, long dx, long dy, long cButtons, long dwExtraInfo);
'@ 

    $SendMouseClick = Add-Type -memberDefinition $signature -name "Win32MouseEventNew" -namespace Win32Functions -passThru 
    if($Button -eq "left")
    {
        $SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0);
        $SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0);
    }
    if($Button -eq "right")
    {
        $SendMouseClick::mouse_event(0x00000008, 0, 0, 0, 0);
        $SendMouseClick::mouse_event(0x00000010, 0, 0, 0, 0);
    }
    if($Button -eq "middle")
    {
        $SendMouseClick::mouse_event(0x00000020, 0, 0, 0, 0);
        $SendMouseClick::mouse_event(0x00000040, 0, 0, 0, 0);
    }

}


}

You can add this function to your profile, or other script, and then you can call it with:

Click-MouseButton "middle"

Solution 2

Well, SendKeys is for simulating keyboard input and not mouse input. If there is a keyboard mechanism to invoke the function then you can use SendKeys. For instance, you can send Alt+«char» if there is a keyboard accelerator configured for a control. Of you can send tab keys then a space key to click a button.

As for actually sending keys with PowerShell, first you have to get a handle to the Window that you want to send keystrokes to. How you get that window handle depends on how the window is created. One way is to use the Win32 API FindWindow. Once you have the Window, you need to make sure it is the foreground window (another Win32 API - SetForegroundWindow does that), then you can start sending it keystrokes. PowerShell V2 and higher allow you to access Win32 APIs via the .NET PInvoke mechanism via the Add-Type cmdlet e.g.:

Start-Process calc.exe

$pinvokes = @'
  [DllImport("user32.dll", CharSet=CharSet.Auto)]
  public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

  [DllImport("user32.dll")]
  [return: MarshalAs(UnmanagedType.Bool)]
  public static extern bool SetForegroundWindow(IntPtr hWnd);
'@

Add-Type -AssemblyName System.Windows.Forms
Add-Type -MemberDefinition $pinvokes -Name NativeMethods -Namespace MyUtils

$hwnd = [MyUtils.NativeMethods]::FindWindow("CalcFrame", "Calculator")
if ($hwnd)
{
    [MyUtils.NativeMethods]::SetForegroundWindow($hwnd)
    [System.Windows.Forms.SendKeys]::SendWait("6")
    [System.Windows.Forms.SendKeys]::SendWait("*")
    [System.Windows.Forms.SendKeys]::SendWait("7")
    [System.Windows.Forms.SendKeys]::SendWait("=")
}

Another possible way, iff the Window is WinForms (or WPF) based and it is running in your PowerShell process, is to use Reflection to reach into the control you want to send a MButtonClick and invoke OnMouseClick yourself. You need a reference to the control but presumably if it is running in your PowerShell process, you created the control and therefore you have a reference to it.

You might find this MSDN article on UI Automation with Windows PowerShell useful. There is also a MSDN topic on simulating mouse and keyboard input that might be helpful.

Share:
18,107

Related videos on Youtube

Mahpooya
Author by

Mahpooya

<?="hello world"; I am only a small programmer. I only attach parts of puzzle of beforehand codes.

Updated on August 28, 2022

Comments

  • Mahpooya
    Mahpooya over 1 year

    How can i send middle mouse click with power shell scripts? I want something like this:

    Add-Type -AssemblyName System.Windows.Forms
    [Windows.Forms.SendKeys]::SendWait('{MButton}')
    
  • Nacht
    Nacht almost 10 years
    this is great except it will only work once - after the type is loaded, add-type will throw an exception saying it's already loaded. load the type and then use [Win32Functions.Win32MouseEventNew] instead of $sendmouseclick
  • davidhigh
    davidhigh over 7 years
    nice answer. Here one can find more information on the used constants. From it one particularly sees that 0x00000002 corresponds to a left-mouse-down move, whereas 0x00000004 is a left-mouse-up move, and similarly for the other mouse clicks.