├── CHANGELOG.md ├── SECURITY.md ├── assets └── images │ └── cursor-default-click-outline.svg ├── extensions ├── sendmouseclick.extension.psm1 ├── Helper.ps1 └── Send-MouseClick.ps1 ├── REUSE.toml ├── CONTRIBUTING.md ├── DEVELOPMENT.md ├── sendmouseclick.extension.nuspec ├── .gitignore ├── README.md └── LICENSES └── Apache-2.0.txt /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | 9 | ## [Unreleased] 10 | 11 | - Nothing worth mentioning yet. 12 | 13 | 14 | ## [1.0.0] - 2023-08-20 15 | 16 | ### Added 17 | 18 | - All functionality and files. 19 | 20 | 21 | [unreleased]: https://github.com/foundata/chocolatey-sendmouseclick.extension/compare/v1.0.0...HEAD 22 | [1.0.0]: https://github.com/foundata/chocolatey-sendmouseclick.extension/releases/tag/v1.0.0 23 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security policy 2 | 3 | ## Reporting a vulnerability 4 | 5 | Please use one of the following ways to report a security vulnerability or concern: 6 | 7 | * GitHub's private [security reporting feature](https://github.com/foundata/chocolatey-sendmouseclick.extension/security/advisories/new) 8 | * Write an email to `security@foundata.com`. 9 | 10 | Please make sure your report contains information about 11 | 12 | * on how to reproduce the issue. 13 | * a fix (if any) which's code is compatible with the project's [licensing](./.reuse/dep5). 14 | * attribution (Name? Email? Any URL to mention?) or if you want to stay anonymous. 15 | 16 | Beside our thanks, you can expect attribution in the release notes of the version shipping a fix if your report was valid. Please note that we do not pay any bug bounties. -------------------------------------------------------------------------------- /assets/images/cursor-default-click-outline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /extensions/sendmouseclick.extension.psm1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | PowerShell Module file that ensures all needed functions and resources are 4 | available. 5 | 6 | .NOTES 7 | SPDX-License-Identifier: Apache-2.0 8 | SPDX-FileCopyrightText: foundata GmbH (https://foundata.com) 9 | #> 10 | 11 | $ErrorActionPreference = 'Stop' # stop on all errors 12 | 13 | $scriptRoot = Split-Path $MyInvocation.MyCommand.Definition 14 | 15 | # get currently defined functions (before dot sourcing additional .ps1 files) 16 | $functionsBefore = Get-ChildItem 'Function:\*' 17 | 18 | # dot source files whose names start with a capital letter, ignore others 19 | Get-ChildItem "${scriptRoot}\*.ps1" | Where-Object { $PSItem.Name -cmatch '^[A-Z]+' } | ForEach-Object { . $PSItem } 20 | 21 | # get currently defined functions (after dot sourcing additional .ps1 files) 22 | $functionsAfter = Get-ChildItem 'Function:\*' 23 | 24 | # export functions whose names start with a capital letter, others are private 25 | $functionsDiff = Compare-Object $functionsBefore $functionsAfter | Select-Object -ExpandProperty 'InputObject' | Select-Object -ExpandProperty 'Name' 26 | $functionsDiff | Where-Object { $PSItem -cmatch '^[A-Z]+'} | ForEach-Object { Export-ModuleMember -Function $PSItem } -------------------------------------------------------------------------------- /REUSE.toml: -------------------------------------------------------------------------------- 1 | version = 1 2 | SPDX-PackageName = "Send-Keys extension for Chocolatey (helper to send keystrokes to a window) (sendkeys.extension)" 3 | SPDX-PackageDownloadLocation = "https://github.com/foundata/chocolatey-sendkeys.extension" 4 | SPDX-PackageSupplier = "foundata GmbH (https://foundata.com)" 5 | SPDX-PackageComment = """ 6 | This project may include calls to Application Programming Interfaces 7 | ("API calls"), as well as their respective specifications and code that 8 | allows software to communicate with other software. API calls to products 9 | or services developed outside of this project are not licensed under the 10 | licensing or usage terms that govern this project. Any use of such API 11 | calls and related external products is subject to applicable additional 12 | agreements with their respective provider and does not alter, expand or 13 | supersede any terms of these additional agreements. 14 | """ 15 | 16 | [[annotations]] 17 | path = "**" 18 | precedence = "closest" 19 | SPDX-FileCopyrightText = "foundata GmbH (https://foundata.com)" 20 | SPDX-License-Identifier = "Apache-2.0" 21 | 22 | [[annotations]] 23 | path = "assets/images/cursor-default-click-outline.svg" 24 | precedence = "closest" 25 | SPDX-FileCopyrightText = "2022 Pictogrammers / Michael Irigoyen (https://pictogrammers.com/contributor/mririgoyen/)" 26 | SPDX-License-Identifier = "Apache-2.0" 27 | SPDX-FileComment = "https://pictogrammers.com/library/mdi/icon/cursor-default-click-outline/, https://pictogrammers.com/docs/general/license/" 28 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Thank you for your interest in contributing. This file provides an overview of the contribution workflow. Summary: 4 | 5 | * Use Issues if you want to report a problem or want to see a feature. 6 | * Use the Chocolatey Community for discussions. 7 | * Create a pull requests (PR) to submit code. 8 | 9 | 10 | ## Issues 11 | 12 | If you spot a problem, have an idea or a feature request, [search if an issue already exists](https://github.com/foundata/chocolatey-sendmouseclick.extension/issues). If a related issue doesn't exist, you can simply open a new issue. 13 | 14 | As a general rule, we don't assign issues to anyone. If you find an issue to work on, you are welcome to open a pull request (PR) with a fix or feature. So if there is an existing issue you are interested in, just work on it. You might leave a comment there to inform others that there is work going on. 15 | 16 | 17 | ## Discussions 18 | 19 | Please use the discussion feature at the [package's Chocolatey Community page](https://community.chocolatey.org/packages/sendmouseclick.extension) for general questions and discussions about the package. 20 | 21 | 22 | ## Pull Requests (PRs) 23 | 24 | Make sure you read [`DEVELOPMENT.md`](./DEVELOPMENT.md), especially the [encoding section](./DEVELOPMENT.md#encoding). Make sure: 25 | 26 | 1. That all source code or other components are compatible with the project's [licensing](./.reuse/dep5) and are traceable. Otherwise, we cannot accept your contribution. 27 | 2. Your code is working / fix the problem / introduce a sane new feature. 28 | 3. Your PR contains a proper commit message with a description of the change and reasoning.
Bonus: reference an issue (if any; PRs without an related issue are still welcome). 29 | 30 | If you do not know how to open a PR, there is plenty of useful information around on the web. Github is also providing quite good documentation: 31 | 32 | * [Forking a repository](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) so that you can make your changes without affecting the original project until we merge them. 33 | * [Branches](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/about-branches#working-with-branches) 34 | * [Pull requests](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork) 35 | -------------------------------------------------------------------------------- /DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | # Development 2 | 3 | This file provides additional information for maintainers and contributors. 4 | 5 | 6 | ## Testing 7 | 8 | Nothing special or automated yet. For the time being, try *at least*: 9 | 10 | 1. Build the nupkg package, install it and watch out for errors and warnings: 11 | ```console 12 | cd ./chocolatey-sendmouseclick.extension 13 | choco pack 14 | choco install sendmouseclick.extension --source='.\' --force 15 | RefreshEnv 16 | ``` 17 | 2. Import the PowerShell module directly, do some function calls and watch out for errors. See the [`README.md` "Usage" section](./README.md#usage) for details. 18 | 19 | 20 | ## Releases 21 | 22 | 1. Do proper [Testing](#testing). Continue only if everything is fine. 23 | 2. Determine the next version number. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). Unlike other Chocolatey packages, there is no underlying software's version to match. 24 | 3. Update the `CHANGELOG.md`(./CHANGELOG.md). Insert a section for the new release. Do not forget the comparison link at the end of the file. 25 | 4. If everything is fine: commit the changes, tag the release and push: 26 | ```console 27 | git tag v -m "version " 28 | git show v 29 | git push origin main --follow-tags 30 | ``` 31 | If something minor went wrong (like missing `CHANGELOG.md` update), delete the tag and start over: 32 | ```console 33 | git tag -d v # delete the old tag locally 34 | git push origin :refs/tags/v # delete the old tag remotely 35 | ``` 36 | This is *only* possible if the package was not already [pushed](https://docs.chocolatey.org/en-us/create/commands/push) to the community package feed. Use a new patch version number otherwise. 37 | 5. [Pack](https://docs.chocolatey.org/en-us/create/commands/pack) the `.nupkg` and [push](https://docs.chocolatey.org/en-us/create/commands/push) it [to the community package feed](https://docs.chocolatey.org/en-us/create/create-packages#push-your-package): 38 | ```console 39 | choco pack 40 | choco apikey add -s "https://push.chocolatey.org/" -k="..." 41 | choco push sendmouseclick.extension..nupkg --source "https://push.chocolatey.org/" 42 | ``` 43 | 44 | 45 | ## Miscellaneous 46 | 47 | ### Encoding 48 | 49 | * Generally: Use UTF-8 encoding with `LF` (Line Feed `\n`) line endings. 50 | * All `*.ps1`, `psm1` and `*.nuspec` files: Please follow [Chocolatey's character encoding rules](https://docs.chocolatey.org/en-us/create/create-packages#character-encoding). Add a Byte Order Mark (BOM) and use `CRLF` (Carriage Return `\r` and Line Feed `\n`) line endings as Chocolatey's general context is Microsoft Windows, Powershell and .NET. 51 | -------------------------------------------------------------------------------- /sendmouseclick.extension.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | sendmouseclick.extension 7 | 1.0.0 8 | https://github.com/foundata/chocolatey-sendmouseclick.extension/ 9 | foundata 10 | 11 | Send-MouseClick extension 12 | foundata 13 | https://github.com/foundata/chocolatey-sendmouseclick.extension/ 14 | https://rawcdn.githack.com/foundata/chocolatey-sendmouseclick.extension/main/assets/images/cursor-default-click-outline.svg 15 | 20 | https://github.com/foundata/chocolatey-sendmouseclick.extension/blob/main/LICENSES/Apache-2.0.txt 21 | true 22 | https://github.com/foundata/chocolatey-sendmouseclick.extension/ 23 | https://github.com/foundata/chocolatey-sendmouseclick.extension/blob/main/README.md 24 | https://github.com/foundata/chocolatey-sendmouseclick.extension/issues 25 | sendmouseclick.extension mouse-events mouse-emulation click non-silent user32.dll 26 | 27 | Helper functions to trigger mouse clicks (send mouse related SendInput calls). 28 | 29 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.toptal.com/developers/gitignore/api/chocolatey,powershell,visualstudiocode,vim,linux,macos,windows,git 2 | # Edit at https://www.toptal.com/developers/gitignore?templates=chocolatey,powershell,visualstudiocode,vim,linux,macos,windows,git 3 | 4 | ### Chocolatey ### 5 | # Exclude packaged modules 6 | *.nupkg 7 | 8 | ### Git ### 9 | # Created by git for backups. To disable backups in Git: 10 | # $ git config --global mergetool.keepBackup false 11 | *.orig 12 | 13 | # Created by git when using merge tools for conflicts 14 | *.BACKUP.* 15 | *.BASE.* 16 | *.LOCAL.* 17 | *.REMOTE.* 18 | *_BACKUP_*.txt 19 | *_BASE_*.txt 20 | *_LOCAL_*.txt 21 | *_REMOTE_*.txt 22 | 23 | ### Linux ### 24 | *~ 25 | 26 | # temporary files which can be created if a process still has a handle open of a deleted file 27 | .fuse_hidden* 28 | 29 | # KDE directory preferences 30 | .directory 31 | 32 | # Linux trash folder which might appear on any partition or disk 33 | .Trash-* 34 | 35 | # .nfs files are created when an open file is removed but is still being accessed 36 | .nfs* 37 | 38 | ### macOS ### 39 | # General 40 | .DS_Store 41 | .AppleDouble 42 | .LSOverride 43 | 44 | # Icon must end with two \r 45 | Icon 46 | 47 | # Thumbnails 48 | ._* 49 | 50 | # Files that might appear in the root of a volume 51 | .DocumentRevisions-V100 52 | .fseventsd 53 | .Spotlight-V100 54 | .TemporaryItems 55 | .Trashes 56 | .VolumeIcon.icns 57 | .com.apple.timemachine.donotpresent 58 | 59 | # Directories potentially created on remote AFP share 60 | .AppleDB 61 | .AppleDesktop 62 | Network Trash Folder 63 | Temporary Items 64 | .apdisk 65 | 66 | ### macOS Patch ### 67 | # iCloud generated files 68 | *.icloud 69 | 70 | ### PowerShell ### 71 | # Exclude packaged modules 72 | *.zip 73 | 74 | # Exclude .NET assemblies from source 75 | *.dll 76 | 77 | ### Vim ### 78 | # Swap 79 | [._]*.s[a-v][a-z] 80 | !*.svg # comment out if you don't need vector files 81 | [._]*.sw[a-p] 82 | [._]s[a-rt-v][a-z] 83 | [._]ss[a-gi-z] 84 | [._]sw[a-p] 85 | 86 | # Session 87 | Session.vim 88 | Sessionx.vim 89 | 90 | # Temporary 91 | .netrwhist 92 | # Auto-generated tag files 93 | tags 94 | # Persistent undo 95 | [._]*.un~ 96 | 97 | ### VisualStudioCode ### 98 | .vscode/* 99 | !.vscode/settings.json 100 | !.vscode/tasks.json 101 | !.vscode/launch.json 102 | !.vscode/extensions.json 103 | !.vscode/*.code-snippets 104 | 105 | # Local History for Visual Studio Code 106 | .history/ 107 | 108 | # Built Visual Studio Code Extensions 109 | *.vsix 110 | 111 | ### VisualStudioCode Patch ### 112 | # Ignore all local history of files 113 | .history 114 | .ionide 115 | 116 | ### Windows ### 117 | # Windows thumbnail cache files 118 | Thumbs.db 119 | Thumbs.db:encryptable 120 | ehthumbs.db 121 | ehthumbs_vista.db 122 | 123 | # Dump file 124 | *.stackdump 125 | 126 | # Folder config file 127 | [Dd]esktop.ini 128 | 129 | # Recycle Bin used on file shares 130 | $RECYCLE.BIN/ 131 | 132 | # Windows Installer files 133 | *.cab 134 | *.msi 135 | *.msix 136 | *.msm 137 | *.msp 138 | 139 | # Windows shortcuts 140 | *.lnk 141 | 142 | # End of https://www.toptal.com/developers/gitignore/api/chocolatey,powershell,visualstudiocode,vim,linux,macos,windows,git 143 | -------------------------------------------------------------------------------- /extensions/Helper.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Helper file to provide shared resources for different parts of the 4 | extension. 5 | 6 | .NOTES 7 | SPDX-License-Identifier: Apache-2.0 8 | SPDX-FileCopyrightText: foundata GmbH (https://foundata.com) 9 | #> 10 | 11 | 12 | Add-Type -Language 'CSharp' -ReferencedAssemblies @('System', 'System.Drawing', 'System.Runtime.InteropServices', 'System.Windows.Forms') -TypeDefinition @" 13 | using System; 14 | using System.Drawing; 15 | using System.Runtime.InteropServices; 16 | using System.Windows.Forms; 17 | 18 | public static class MouseClick 19 | { 20 | // More info on INPUT structure (winuser.h): 21 | // https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-input 22 | [StructLayout(LayoutKind.Sequential)] 23 | public struct INPUT 24 | { 25 | public int type; // 0 = INPUT_MOUSE, 1 = INPUT_KEYBOARD, 2 = INPUT_HARDWARE 26 | public MOUSEINPUT mInput; 27 | } 28 | 29 | // More info on MOUSEINPUT structure (winuser.h): 30 | // https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput 31 | [StructLayout(LayoutKind.Sequential)] 32 | public struct MOUSEINPUT 33 | { 34 | public int dx; 35 | public int dy; 36 | public int mouseData; 37 | public int dwFlags; 38 | public int time; 39 | public IntPtr dwExtraInfo; 40 | } 41 | 42 | // See https://learn.microsoft.com/en-us/windows/win32/api/winuser/ns-winuser-mouseinput 43 | // for info about the following bit flags that specify various aspects of mouse motion, 44 | // button clicks and other mouse events or functions. 45 | private const int MOUSEEVENTF_ABSOLUTE = 0x8000; 46 | private const int MOUSEEVENTF_HWHEEL = 0x1000; 47 | private const int MOUSEEVENTF_LEFTDOWN = 0x0002; 48 | private const int MOUSEEVENTF_LEFTUP = 0x0004; 49 | private const int MOUSEEVENTF_MIDDLEDOWN = 0x0020; 50 | private const int MOUSEEVENTF_MIDDLEUP = 0x0040; 51 | private const int MOUSEEVENTF_MOVE = 0x0001; 52 | private const int MOUSEEVENTF_RIGHTDOWN = 0x0008; 53 | private const int MOUSEEVENTF_RIGHTUP = 0x0010; 54 | private const int MOUSEEVENTF_WHEEL = 0x0080; 55 | private const int MOUSEEVENTF_XDOWN = 0x0100; 56 | private const int MOUSEEVENTF_XUP = 0x0200; 57 | 58 | [DllImport("user32.dll")] 59 | extern static uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize); 60 | 61 | public static void LeftClickAtPoint(int x, int y) 62 | { 63 | // move 64 | INPUT[] input = new INPUT[3]; 65 | input[0].mInput.dx = x * (65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width); 66 | input[0].mInput.dy = y * (65535 / System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height); 67 | input[0].mInput.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; 68 | 69 | // left button down 70 | input[1].mInput.dwFlags = MOUSEEVENTF_LEFTDOWN; 71 | 72 | // left button up 73 | input[2].mInput.dwFlags = MOUSEEVENTF_LEFTUP; 74 | SendInput(3, input, Marshal.SizeOf(input[0])); 75 | } 76 | } 77 | "@ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Send-MouseClick extension for Chocolatey (`sendmouseclick.extension`) 2 | 3 | **This project is *not* associated with the official [Chocolatey](https://chocolatey.org/) product or team, nor with [Chocolatey Software, Inc.](https://chocolatey.org/contact/).** 4 | 5 | A [Chocolatey extension](https://docs.chocolatey.org/en-us/features/extensions) providing helper functions to send mouse clicks (mouse related SendInput calls). These functions may be used in Chocolatey install and uninstall scripts by declaring this package a dependency in your package's `.nuspec`. 6 | 7 | 8 | ## Installation 9 | 10 | As the package is an extension, it gets usually installed automatically as a dependency. However, you can still install it manually: 11 | 12 | ```console 13 | choco install sendmouseclick.extension 14 | ``` 15 | 16 | 17 | ## Usage 18 | 19 | To create a package with the ability to use a function from this extension, add the following to your `.nuspec` specification: 20 | 21 | ```xml 22 | 23 | 24 | 25 | ``` 26 | 27 | It is possible to import the module directly in your `PS >`, so you can try out the main functionality directly: 28 | 29 | ```powershell 30 | # import the modules 31 | Import-Module "${env:ChocolateyInstall}\helpers\chocolateyInstaller.psm1" 32 | Import-Module "${env:ChocolateyInstall}\extensions\sendmouseclick\*.psm1" 33 | 34 | # get a list of all functions 35 | Get-Command -Module 'sendmouseclick.extension' 36 | 37 | # get help and examples for a specific function 38 | Get-Help Send-MouseClick -Detailed 39 | 40 | # left-click on the center of the current primary screen (implies -Position 'Center') 41 | Send-MouseClick 42 | 43 | # left-click at the current cursor position 44 | Send-MouseClick -Position $null 45 | 46 | # bring the first window that contains the name 'foo' to the front, focus it and 47 | # left-click on the center of the current primary screen 48 | Send-MouseClick -Query 'foo' 49 | 50 | # left-click at the position X100, Y200 of the current primary screen 51 | Send-MouseClick -Position (100, 200) 52 | 53 | # bring the first window that equals the name 'foo' to the front, focus it and 54 | # left-click on the center of the current primary screen 55 | Send-MouseClick -Query '^foo$' 56 | ``` 57 | 58 | But keep in mind that functions of Chocolatey extension may only work correctly in the context of Chocolatey install and uninstall scripts. 59 | 60 | 61 | ## Licensing, copyright 62 | 63 | 64 | Copyright (c) 2023, 2024 foundata GmbH (https://foundata.com) 65 | 66 | This project is licensed under the Apache License 2.0 (SPDX-License-Identifier: `Apache-2.0`), see [`LICENSES/Apache-2.0.txt`](LICENSES/Apache-2.0.txt) for the full text. 67 | 68 | The [`REUSE.toml`](REUSE.toml) file provides detailed licensing and copyright information in a human- and machine-readable format. This includes parts that may be subject to different licensing or usage terms, such as third-party components. The repository conforms to the [REUSE specification](https://reuse.software/spec/). You can use [`reuse spdx`](https://reuse.readthedocs.io/en/latest/readme.html#cli) to create a [SPDX software bill of materials (SBOM)](https://en.wikipedia.org/wiki/Software_Package_Data_Exchange). 69 | 70 | 71 | [![REUSE status](https://api.reuse.software/badge/github.com/foundata/chocolatey-sendmouseclick.extension)](https://api.reuse.software/info/github.com/foundata/chocolatey-sendmouseclick.extension) 72 | 73 | 74 | ## Author information 75 | 76 | This Chocolatey extension was created and is maintained by [foundata](https://foundata.com/). If you like it, you might [buy them a coffee](https://buy-me-a.coffee/chocolatey-sendmouseclick.extension/). This is a community project and *not* associated with the official [Chocolatey](https://chocolatey.org/) product or team, nor with [Chocolatey Software, Inc.](https://chocolatey.org/contact/). 77 | -------------------------------------------------------------------------------- /extensions/Send-MouseClick.ps1: -------------------------------------------------------------------------------- 1 | <# 2 | .SYNOPSIS 3 | Function file. 4 | 5 | .NOTES 6 | SPDX-License-Identifier: Apache-2.0 7 | SPDX-FileCopyrightText: foundata GmbH (https://foundata.com) 8 | #> 9 | 10 | 11 | function Send-MouseClick { 12 | <# 13 | .SYNOPSIS 14 | Sends mouse clicks to the active application with optional, automatic window 15 | focus and optional delays (before and after clicking). Mostly a wrapper 16 | around different mouse click related user32.dll SendInput calls. 17 | 18 | .LINK 19 | https://docs.microsoft.com/en-us/dotnet/desktop/winforms/input-mouse/how-to-simulate-events 20 | #> 21 | 22 | [CmdletBinding()] 23 | Param( 24 | [Parameter(Mandatory = $False, 25 | HelpMessage = 'Where to send the click (this does not move the cursor, only sending the click as it would have been moved there and back to the original position). Use $False, $null or an empty string to send the click at the current cursor position. Use the string "Center" to send the click to the center of the current primary screen. User an array of integers (x, y) to define coordinates as you whish. Defaults to "Center".')] 26 | $Position = 'Center', 27 | 28 | [Parameter(Mandatory = $False, 29 | HelpMessage = 'What kind of mouse click to send. Defaults to "Left".')] 30 | [ValidateSet('Left')] 31 | [String]$Type = 'Left', 32 | 33 | [Parameter(Mandatory = $False, 34 | HelpMessage = 'Array of integers. Seconds to wait before executing the mouse event and afterwards. Defaults to (0, 2).')] 35 | [ValidateScript({ 36 | if (!($Delay -is [array]) -or ($Delay.count -ne 2)) { 37 | Throw 'Send-MouseClick: -Delay has to be an array of integers with two elements.' 38 | } else { 39 | $True 40 | } 41 | })] 42 | [Array]$Delay = @(0, 2), 43 | 44 | [Parameter(Mandatory = $False, 45 | HelpMessage = 'An optional -Query for Use-Window (which will be called before the mouse click if a query is given).')] 46 | [String]$Query = '' 47 | ) 48 | 49 | Begin { 50 | if (!(Test-Path variable:SendMouseClickInitDone -ErrorAction 'SilentlyContinue')) { 51 | Add-Type -AssemblyName System.Drawing 52 | Add-Type -AssemblyName System.Windows.Forms 53 | Set-Variable -Name 'SendMouseClickInitDone' -Value $True -Option 'Constant' -Scope 'Global' -Force 54 | } 55 | } 56 | 57 | Process { 58 | $Coordinates = @(0, 0) 59 | switch ($Position) { 60 | # center of primary screen 61 | 'Center' { 62 | # TODO Check if this is DPI aware, not tested yet. Cf. bit.ly/3E7L4Z3, bit.ly/3hsEySV 63 | # TODO Check if PrimaryScreen.WorkingArea is better (which returns the desktop area 64 | # of the display, excluding taskbars, docked windows, and docked tool bars)? 65 | # Clarify where do new windows get placed? Center of screen or working area? 66 | # Cf. System.Windows.WindowStartupLocation.CenterScreen 67 | $Coordinates[0] = [int]([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width / 2) 68 | $Coordinates[1] = [int]([System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height / 2) 69 | } 70 | 71 | # user defined position 72 | {(($Position -is [array]) -and ($Position.count -eq 2))} { 73 | $Coordinates[0] = [int]$Position[0] 74 | $Coordinates[1] = [int]$Position[1] 75 | } 76 | 77 | # cursor's current position 78 | {($Position -eq $False -or ([string]::IsNullOrEmpty($Position)))} { 79 | $Coordinates[0] = [int]([System.Windows.Forms.Cursor]::Position.X) 80 | $Coordinates[1] = [int]([System.Windows.Forms.Cursor]::Position.Y) 81 | } 82 | 83 | default { Throw ('Send-MouseClick: Unknown position "{0}"' -f "${Position}") } 84 | } 85 | 86 | # force integer casting 87 | $Delay[0] = [int]$Delay[0] 88 | $Delay[1] = [int]$Delay[1] 89 | 90 | # delay before 91 | if ($Delay[0] -gt 0) { 92 | Write-Host ('Send-MouseClick: Will wait {0} seconds (delay before sending the click(s)).' -f $Delay[0]) 93 | Start-Sleep $Delay[0] 94 | } 95 | 96 | # bring to front and activate a target window 97 | if ($Query -ne $False -and !([string]::IsNullOrEmpty($Query))) { 98 | Use-Window -Query $Query 99 | } 100 | 101 | Write-Host ('Send-MouseClick: "{0}" click at (X{1}, Y{2}).' -f "${Type}", $Coordinates[0], $Coordinates[1]) 102 | switch ($Type) { 103 | 'Left' { [MouseClick]::LeftClickAtPoint($Coordinates[0], $Coordinates[1]) } 104 | # 'LeftDouble' { FIXME to be implemented } 105 | # 'Right' { FIXME to be implemented } 106 | default { Throw ('Send-MouseClick: Unknown click type "{0}"' -f "${Type}") } 107 | } 108 | 109 | # delay after 110 | if ($Delay[1] -gt 0) { 111 | Write-Host ('Send-MouseClick: Will wait {0} seconds (delay after sending the click(s)).' -f $Delay[1]) 112 | Start-Sleep $Delay[1] 113 | } 114 | } 115 | 116 | End { } 117 | } -------------------------------------------------------------------------------- /LICENSES/Apache-2.0.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 30 | 31 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 32 | 33 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 34 | 35 | (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and 36 | 37 | (b) You must cause any modified files to carry prominent notices stating that You changed the files; and 38 | 39 | (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 40 | 41 | (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 42 | 43 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 44 | 45 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 46 | 47 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 48 | 49 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 50 | 51 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 52 | 53 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 54 | 55 | END OF TERMS AND CONDITIONS 56 | 57 | APPENDIX: How to apply the Apache License to your work. 58 | 59 | To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. 60 | 61 | Copyright [yyyy] [name of copyright owner] 62 | 63 | Licensed under the Apache License, Version 2.0 (the "License"); 64 | you may not use this file except in compliance with the License. 65 | You may obtain a copy of the License at 66 | 67 | http://www.apache.org/licenses/LICENSE-2.0 68 | 69 | Unless required by applicable law or agreed to in writing, software 70 | distributed under the License is distributed on an "AS IS" BASIS, 71 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 72 | See the License for the specific language governing permissions and 73 | limitations under the License. 74 | --------------------------------------------------------------------------------