This script does a few things. I will break it apart into separate posts that deal with each bit, but for now here is the whole lot.
The purpose of this script is to;
- move the mouse to specific screen coordinates
- click mouse buttons at those coordinates in order to drive an application
- give the application time to respond
- take a screenshot
- save the screenshot as required
- cater for multiple screens in a horizontal configuration
There are some functions in this one not specifically related to the objectives, but for reasons I won’t go into here, I generally try to keep all scripts as self-contained as possible. I will try to break this out when I get time.
#region Includes # ====================== Add some required bits and import some DLLs # System drawing and windows forms [Reflection.Assembly]::LoadWithPartialName("System.Drawing") [Reflection.Assembly]::LoadWithPartialName(“System.Windows.Forms”) # Some mousey things $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 # Stopwatch for timing the whole process $SWScriptTime = [Diagnostics.Stopwatch]::StartNew() #endregion Includes #region Variables # ====================== Define Some Screen Variables # Screen size related variables $baseScreenSizeX = 1920 #pixles $baseScreenSizeY = 1080 #pixles $sleepPeriod = 20 #seconds $baseimagepath = "D:\RoboClicky\images\" # Log File Variables $appVersion = "RoboClicky Version 2" $logMonth = (Get-Date -Format "yyyy-MM-") $logDay = (Get-Date -Format "dd-") $basePath = "" $logFile = "" $logDestinationDetail = $basepath + "D:\RoboClicky\"+$logmonth+$logday+"RoboClicky_Detail_Log.txt" # Temporary session log $global:currentLog = "" #endregion Variables #region FUNCTIONS # ====================== FUNCTIONS #region GenericFunctions # I use these in many of my scripts # ====================== Format Date Function function GetDateFormatted(){ Return (Get-Date -Format "yyyy-MM-dd HH:mm:ss") } function GetDateFormattedForPaths(){ Return (Get-Date -Format "yyyy-MM-dd HHmmss") } # ====================== Logging Function function LogThis($logthisstring){ $logEntry = (GetDateFormatted) + "# " + $logthisstring $global:currentLog = $global:currentLog + "`n" + $logentry $logEntry | Out-File $logDestinationDetail -Append $logEntry | Out-host } # ====================== Path Testing Function function CheckFileExists($checkPath){ $filexists = (test-path ($checkPath)) logthis("Check Path: " + $checkPath + " | file exists = " + $filexists) return $filexists } # ====================== Exit Block $ExitNow = { # find me a line Morpheus $SWScriptTime.Stop() logthis("EXIT NOW! Script complete in " + $SWScriptTime.Elapsed + " ... welcome to the real world Neo ...") $global:currentLog | Out-File $currentLogPath -Force exit } #endregion GenericFunctions #region RoboClickyFunctions # ====================== Return mouse to 0,0 coordinates function mooseHome(){ logthis ("F: moving mouse now to coordinates: 0,0") [Windows.Forms.Cursor]::Position = "0,0" return } # ====================== Move mouse to specified coordinates and sleep for sleep period function mooseMove($screenNumber, $xCoords, $yCoords, $label, [boolean]$isrelative, $loadWaitPeriod){ # NOTE::: This code only handles displays that have left to right numbering. Future upgrade will include full relative screen handling. Because it would be awesome! #Log some things logthis ("F: mooseMove function called with paramaters;") logthis (" screenNumber = "+$screenNumber) logthis (" xCoords = "+$xCoords) logthis (" yCoords = " +$yCoords) logthis (" label = " + $label) logthis (" isrelative = " + $isrelative) logthis ("F: calculating absolute coordinates") #Set Absolute X coordinates of the screen (which are relative to the entire screen canvas) $absolutexCoords = $xCoords + ($baseScreenSizeX * $screenNumber) $absoluteyCoords = $yCoords $coords = "$($absolutexCoords),$($absoluteyCoords)" logthis (" ... "+$coords) logthis ("F: moving mouse now to screen " + $screenNumber + ", relative coordinates: x=" + $xCoords + ", y=" + $yCoords + ", absolute coordinates: "+$coords) # move the mouse [Windows.Forms.Cursor]::Position = $coords # perform left mouse click using mooseClick function mooseClick logthis ("F: sleeping for: " + $sleepPeriod +" seconds to allow for screen rendering") sleep $loadWaitPeriod mooseHome return } # ====================== Perform left mouse click function mooseClick { logthis ("F: left mouse clicking now") $SendMouseClick::mouse_event(0x00000002, 0, 0, 0, 0); #Left Mouse Down $SendMouseClick::mouse_event(0x00000004, 0, 0, 0, 0); #Left Mouse Up return } # ====================== Grab ScreenShot of screen X function screenshot($displaynumber,$screenshotname) { logthis ("F: Performing screen capture of display "+$displaynumber) #$bounds = [Drawing.Rectangle]::FromLTRB($screen.Left, $screen.Top, $screen.right, $screen.bottom) #$bounds = [Drawing.Rectangle]::FromLTRB(-236, -1080, 1684, 0) #calculating cooridinates for screen capture logthis("#calculating cooridinates for screen capture") $captureLeft = $baseScreenSizeX * $displaynumber $captureTop = 0 # fixed value in this version $captureRight = ($baseScreenSizeX * $displaynumber) + 1920 $captureBottom = 1080 # fixed value in this version $bounds = [Drawing.Rectangle]::FromLTRB($captureLeft, $captureTop, $captureRight, $captureBottom) $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height $graphics = [Drawing.Graphics]::FromImage($bmp) logthis("F: Screen capturing from absolute range:") logthis(" Left: "+$captureLeft) logthis(" Top: "+$captureTop) logthis(" Right: "+$captureRight) logthis(" Bottom: "+$captureBottom) # create image $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size) $path=$baseimagepath + $screenshotname + ".png" logthis ("F: Saving screen capture as "+$path) $bmp.Save($path) $graphics.Dispose() $bmp.Dispose() } function refreshIE($refreshStringRef) { # Function to refresh IE window with a specific name logthis("F: Refreshing IE Where name of window contains '" + $refreshStringRef +"'") $shell = new-object -ComObject shell.application $shell.windows() | Where-Object { $_.document.url -like $('*' + $refreshStringRef + '*')} | ForEach-Object { $_.refresh() } } #endregion RoboClickyFunctions #endregion FUNCTIONS #region Mainline # Step 1 - Refresh IE window containing application visualisation refreshie -refreshStringRef "ie-application-window-name" logthis ("waiting for ie-application-window-name") sleep 30 # Step 2 - Move mouse around the visualisation using the mooseMove function, then snap an image of it using the screenshot function. # Zone A mooseMove -screenNumber 6 -xCoords 685 -yCoords 21 -label "Zone A" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_A" # Zone B mooseMove -screenNumber 6 -xCoords 797 -yCoords 21 -label "Zone B" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_B" # Zone C mooseMove -screenNumber 6 -xCoords 908 -yCoords 21 -label "Zone C" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_C" # Zone D mooseMove -screenNumber 6 -xCoords 1020 -yCoords 21 -label "Zone D" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_D" # Zone E mooseMove -screenNumber 6 -xCoords 1131 -yCoords 21 -label "Zone E" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_E" # Zone F mooseMove -screenNumber 6 -xCoords 1242 -yCoords 21 -label "Zone F" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_F" # Zone G mooseMove -screenNumber 6 -xCoords 1354 -yCoords 21 -label "Zone G" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_G" # Zone H mooseMove -screenNumber 6 -xCoords 1465 -yCoords 21 -label "Zone H" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_A" # Zone etc... mooseMove -screenNumber 6 -xCoords 1576 -yCoords 21 -label "Zone etc... and so on" -isrelative $true -loadWaitPeriod 25 screenshot -displaynumber 6 -screenshotname "Dashboard_Zone_Summary" &$exitnow #endregion Mainline