CursorPosition.psm1
$Script:CursorRepository = @() # we are creating this class to standardize to object because we are going to use one function's output in the other function. class CursorPosition { [int] $Id [string] $Name [int] $X [int] $Y [datetime] $TimeStamp CursorPosition([int]$X, [int]$Y) { $this.Id = $this.GetNewId() $this.Name = (Get-Date -Format "yyyy-MM-dd HH:mm:ss") $this.X = $X $this.Y = $Y $this.TimeStamp = Get-Date } CursorPosition([int]$X, [int]$Y, [string]$Name) { $this.Id = $this.GetNewId() $this.Name = $Name $this.X = $X $this.Y = $Y $this.TimeStamp = Get-Date } CursorPosition([int]$X, [int]$Y, [string]$Name, [datetime]$TimeStamp) { $this.Id = $this.GetNewId() $this.Name = $Name $this.X = $X $this.Y = $Y $this.TimeStamp = $TimeStamp } [int] GetNewId() { [int]$i = 1 [bool]$Loop = $true while ($Loop) { if ($Script:CursorRepository.Id -contains $i) { $i++ } else { $Loop = $false } } return $i } } function Get-Cursor { [CmdletBinding(DefaultParameterSetName = "Id")] param ( [Parameter(Mandatory = $false, ParameterSetName = "Id")] [int] $Id, [Parameter(Mandatory = $false, ParameterSetName = "Name")] [string] $Name, [Parameter(Mandatory = $false, ParameterSetName = "List")] [switch] $List ) begin { # Get current location $CurrentPosition = [System.Windows.Forms.Cursor]::Position } process { # create an instance of CursorPosition just to standardize the output $Position = [CursorPosition]::new($CurrentPosition.X, $CurrentPosition.Y) } end { if ($Id) { Write-Output ($Script:CursorRepository | Where-Object {$_.id -eq $Id}) } elseif ($Name) { Write-Output ($Script:CursorRepository | Where-Object {$_.Name -eq $Name}) } elseif ($List) { Write-Output $Script:CursorRepository } else { Write-Output $Position } } } function Set-Cursor { [CmdletBinding(DefaultParameterSetName = "Position")] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Id")] [Int] $id, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Position")] [int] $X, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Position")] [Int] $Y ) begin { } process { # I usually assign variables in begin block. However, if X and Y info comes from pipeline, they would be processed in process block and i would see the info in begin block # Convert type of Int values to type of point, so the system can understant what all those numbers are for if ($id) { $Item = Get-Cursor -Id $id $Position = [System.Drawing.Point]::new($Item.X, $Item.Y) } else { $Position = [System.Drawing.Point]::new($X, $Y) } # set the cursor to new position provided [System.Windows.Forms.Cursor]::Position = $Position } end { Write-Verbose "Cursor position is set to $($Position.X)X$($Position.Y)" } } function Add-Cursor { [CmdletBinding()] param ( [string] $Name, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [int] $X, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [Int] $Y ) begin { } process { if ($Name) { $Cursor = [CursorPosition]::new($X, $Y, $Name) } else { $Cursor = [CursorPosition]::new($X, $Y) } $Script:CursorRepository += $Cursor } end { Write-Output $Cursor } } function Remove-Cursor { [CmdletBinding(DefaultParameterSetName = "Id")] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "Id")] [int] $Id, [Parameter(Mandatory = $true, ParameterSetName = "List")] [switch] $All ) begin { } process { if ($Id) { $Item = Get-Cursor -Id $Id $Script:CursorRepository = $Script:CursorRepository | Where-Object {$_ -ne $Item} } elseif ($All) { $Script:CursorRepository = @() } } end { Write-Verbose "Cursor(s) have been removed." } } function Export-Cursor { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true)] [CursorPosition] $CursorList, [Parameter(Mandatory = $true)] [ValidateScript( {Test-Path $_})] [string] $Path, [string] $Name, [switch] $OpenLocation ) begin { if ($Name) { if ($Name -match "([a-zA-Z0-9\s_\\.\-\(\):])+(.csv)$") { $FilePath = Join-Path -Path $Path -ChildPath $Name } else { $FilePath = Join-Path -Path $Path -ChildPath "$Name.csv" } } else { $FilePath = "$(Get-Date -Format "yyyy-MM-dd_HH-mm-ss").csv" } } process { try { Get-Cursor -List | Export-Csv -Path $FilePath -NoTypeInformation -Force -Confirm:$false } catch { Write-Error "Cursor List couldn't be exported." } } end { Write-Host "Cursor List has been exported to $FilePath" if ($OpenLocation) { Invoke-Item "$FilePath\.." } } } function Import-Cursor { [CmdletBinding()] param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true)] [ValidateScript({Test-Path $_})] [string] $Path, [switch] $Overwrite ) begin { } process { if ($Overwrite) { $Script:CursorRepository = @() Write-Verbose "Cursor List has been freed up" } try { $Items = Import-Csv -Path $Path $Items | ForEach-Object { $Item = [CursorPosition]::new($_.X,$_.Y,$_.Name,[datetime]$_.TimeStamp) $Script:CursorRepository += $Item } } catch { Write-Error "Some or all of the items couldn't be imported" } } end { if($Error.Count -lt 1) { Write-Host "$Path has been imported." } } } |