Leaderboard
Popular Content
Showing content with the highest reputation on 06/11/2019 in all areas
-
$path = @ScriptDir $filter = "*_stripped.au3" $search = _FileListToArrayRec($path, $filter) now it uses regex2 points
-
The code is solid and simple, it can almost explain itself. This is the native autoit way to do the "imagesearch", no 3rd party .dll needed. It gets "your.bmp", and "screenshot.bmp" ----> Convert the .bmp files into 2D-Arrays (Malkey's function) ----> Compare the 2D-arrays, return the matched position. Tested on: Windows 7; Windows server 2008R2; Windows 10 1809. Pros: It is native. No extra .dll needed It is super robust. (I used to have lots of funny results using other imagesearch libs). It gets screenshot the same you get your screenshot crop, so it always gets a solid result, and 100% accurate. The code is very simple and friendly, all level users can understand and use it. Cons: It is slow to convert your.big.screen.bmp into a 2D-array, and may consume 200+MB of memory and may take 5 - 20 seconds to return the result. (the actual search in an array is fast, but the conversion from .bmp to array is slow. The speed depends on your CPU speed and your screen size). Correct: now optimized, it's ~5 seconds and ~ 70MB ram usage. It is a pixel-by-pixel color-code strict comparison in the "array-in-array" search, so you have to use the 24-bit BMP file, no "Tolerance" allowed. 2019-Jun-11: script update: Same day updated: Update example; Optimize the algorithm for performance, now most computers can get the result in ~5 seconds, using ~70MB temporary memory, for the 1920x1080 resolution screen. 2019-Jun-12 script update: It now uses "PrintScreen" hotkey to save the screenshot.bmp (restores the user's old clipboard content after it is done) ~This is the only way to make sure the screenshot matches exactly what the user is seeing, after doing dozens of harsh tests. The reason: The UDF "ScreenCapture" and "ImageSearch.dll" are not reliable for an unknown reason. Some window/dialogue special drawings are "invisible" in their screenshots. But the "PrintScreen" key -> Clipboard -> screenshot.bmp, this method always catches exact things showing on the screen. #include <GDIPlus.au3> #include <ClipBoard.au3> ;Sinple Example.================== the 1.bmp is what you want to find on your screen $result = _ScreenSearchBmp("1.bmp") if $result[0] = 0 Then MsgBox(0,"","not found") Else MouseMove($result[0],$result[1],20) ;move mouse to the result EndIf ;Example End.================== You can "include" this file after you remove this "Example" part here. ;=============================================================================== ; ; Description: Main Function. Find the position of an image on the desktop ; Parameter(s): ; $center = 1 - Set where the returned x,y location of the image is. ; default 1 means center, 0 means top-left ; ; Return Value(s): On Success - Returns the array of matched position [x,y] on your screen. ; On Failure - Returns array [0,0] (BTW, there is no position 0,0 on a screen, so it means error) ; ; Note: Warning: The BMP file must be a 24-bit BMP (windows default) ; ;=============================================================================== Func _ScreenSearchBmp($file,$center=1) local $pixelarray,$screenarray ;get both your image.bmp and screenshot.bmp into pixel-by-pixel 2D arrays _FileImageToArray($file, $pixelarray) _Clip_screenshot(@TempDir & "\screenshot.bmp") _FileImageToArray(@TempDir & "\screenshot.bmp",$screenarray) FileDelete(@TempDir & "\screenshot.bmp") ;compare the 2 2D-arrays local $result = _2darray_in_2darray($screenarray,$pixelarray) ;result tidy up, for if $center=1, and for if not found. Local $aresult[2] $aresult[0] = $result[0] $aresult[1] = $result[1] if $aresult[0] = 0 then Return $aresult ;if not found , return 0 0 here if $center = 1 then $aresult[0] = $result[0]+ Round(UBound($pixelarray,1)/2) if $center = 1 then $aresult[1] = $result[1]+ Round(UBound($pixelarray,2)/2) Return $aresult ;if ALL GOOD, and $center=1 then return the center of the image here. EndFunc ;=============================================================================== ; Code by Malkey, converts .bmp into 2D array pixal by pixal. : thanks man! ;=============================================================================== Func _FileImageToArray($filename, ByRef $aArray) Local $Reslt, $stride, $format, $Scan0, $iW, $iH, $hImage Local $v_Buffer, $width, $height Local $i, $j _GDIPlus_Startup() $hImage = _GDIPlus_ImageLoadFromFile($filename) $iW = _GDIPlus_ImageGetWidth($hImage) $iH = _GDIPlus_ImageGetHeight($hImage) $Reslt = _GDIPlus_BitmapLockBits($hImage, 0, 0, $iW, $iH, $GDIP_ILMREAD, $GDIP_PXF32ARGB) ;Get the returned values of _GDIPlus_BitmapLockBits () $width = DllStructGetData($Reslt, "width") $height = DllStructGetData($Reslt, "height") $stride = DllStructGetData($Reslt, "stride") $format = DllStructGetData($Reslt, "format") $Scan0 = DllStructGetData($Reslt, "Scan0") Dim $aArray[$width][$height] For $i = 0 To $iW - 1 For $j = 0 To $iH - 1 $aArray[$i][$j] = DllStructGetData(DllStructCreate("dword", $Scan0 + ($j * $stride) + ($i * 4)), 1) Next Next _GDIPlus_BitmapUnlockBits($hImage, $Reslt) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Return EndFunc ;==>_FileImageToArray ;=============================================================================== ; ; Description: ; My code, search a 2D array inside another 2d array ; If found, return the positon of first element ; If error or not found, return array [0,0]. Because the very first match would be [1,1], "0" means something wrong. ; eg. search a 2d array ; [1,2,3,4] ; [5,6,7,8] ; [9,0,1,2] ; for: ; [7,8] ; [1,2] ; You will get result [2,3] (means, matched, first element position is row 2, colunm 3) ; ; Parameter(s): ; ; Return Value(s): On Success - Returns the array of matched [x,y], the top-left element position in the source. ; On Failure - Returns [0,0] ; ; ;=============================================================================== Func _2darray_in_2darray($source,$search) ;get the size of the both arrays local $sourcerow = UBound($source,1) Local $sourcecol = UBound($source,2) local $searchrow = UBound($search,1) Local $searchcol = UBound($search,2) ;error input cheching, if error return position 0,0 if $sourcerow = 0 or $sourcecol = 0 or $searchrow = 0 or $searchcol = 0 then Local $aPeople[2] $aPeople[0] = 0 $aPeople[1] = 0 Return $aPeople EndIf ; A crazy 4-for-loops, compare every x,y of search array in every x,y in source array for $ssr = 1 to $sourcerow - $searchrow +1 for $ssc = 1 to $sourcecol - $searchcol +1 for $sr = 1 to $searchrow for $sc = 1 to $searchcol ;if an element not match, go back, search for next if $search[$sr-1][$sc-1] <> $source[$ssr+$sr-2][$ssc+$sc-2] then ContinueLoop 3 Next Next ;if the loop passed all elements test, made it here, means the result is found! congress! lets return the result: Local $aPeople[2] $aPeople[0] = $ssr $aPeople[1] = $ssc Return $aPeople Next Next ;all the loops finished, no result found. return [0,0] Local $aPeople[2] $aPeople[0] = 0 $aPeople[1] = 0 Return $aPeople EndFunc ; #FUNCTION# ==================================================================================================================== ; Name ..........: _Clip_screenshot ; Description ...: This get a screenshot.bmp using "Print Screen" key, so the image is EXACT same image you use "Print Screen" key, to avoid funny results. ; Syntax ........: _Clip_screenshot($file) ; Parameters ....: $file - The location of the screen shot .bmp file you want it to save ; Return values .: None ; Author ........: Kyle ; =============================================================================================================================== Func _Clip_screenshot($file) local $tempdata = _ClipBoard_GetData() ;save current user's clipboard Send("{PRINTSCREEN}") sleep(200) If _ClipBoard_IsFormatAvailable($CF_BITMAP) Then _ClipBoard_Open(0) $hClipboardImage = _ClipBoard_GetDataEx($CF_BITMAP) _ClipBoard_Close() _GDIPlus_Startup() $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP($hClipboardImage) Local $iX = _GDIPlus_ImageGetWidth($hBitmap) Local $iY = _GDIPlus_ImageGetHeight($hBitmap) Local $hClone = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, $iX, $iY, $GDIP_PXF24RGB) ;make sure its 24bit bmp _GDIPlus_ImageDispose($hBitmap) $hBitmap = $hClone $sCLSID = _GDIPlus_EncodersGetCLSID("BMP") _GDIPlus_ImageSaveToFileEx($hBitmap, $file, $sCLSID, 0) _GDIPlus_BitmapDispose($hBitmap) _GDIPlus_Shutdown() EndIf _ClipBoard_SetData($tempdata) ; restore user clipboard EndFunc Remove the "example" part then you can include this code as a file.1 point
-
ListUserSessions
BigDaddyO reacted to argumentum for a topic
..was looking for UserName from SessionID so I put this together #include <Debug.au3> ; for _DebugArrayDisplay() ; all you can get from _WTSQuerySessionInformation() Global $i = _WTSQuerySessionInformation(-1, 4) ; current user's SessionId Global $__a_WTS_INFO_CLASS = StringSplit("WTSInitialProgram,WTSApplicationName,WTSWorkingDirectory,WTSOEMId,WTSSessionId,WTSUserName," & _ "WTSWinStationName,WTSDomainName,WTSConnectState,WTSClientBuildNumber,WTSClientName,WTSClientDirectory,WTSClientProductId,WTSClientHardwareId," & _ "WTSClientAddress,WTSClientDisplay,WTSClientProtocolType,WTSIdleTime,WTSLogonTime,WTSIncomingBytes,WTSOutgoingBytes,WTSIncomingFrames," & _ "WTSOutgoingFrames,WTSClientInfo,WTSSessionInfo,WTSSessionInfoEx,WTSConfigInfo,WTSValidationInfo,WTSSessionAddressV4,WTSIsRemoteSession", ",", 2) For $n = 0 To UBound($__a_WTS_INFO_CLASS) -1 ConsoleWrite($n & @TAB & StringLeft($__a_WTS_INFO_CLASS[$n] & ' ________________', 24) & " " & _WTSQuerySessionInformation($i, $n, 1) & @CRLF) Next Global $a = ListUserSessions() _DebugArrayDisplay($a, "ListUserSessions()") Func ListUserSessions() ; mod. of https://www.autoitscript.com/forum/topic/139774-dllcall-and-returned-pointers/?do=findComment&comment=980850 Local $_Self_SessionId = _WTSQuerySessionInformation(-1, 4) ; -1 = current user ; 4 = WTSSessionId Local Enum $e_IsSelf_SessionId, $e_SessionName, $e_UserName, $e_SessionId, $e_StateName, $e_StateInt, $e_ClientName, $e_ClientIp, $e_Domain, $e_UBound Local Const $tagWTS_SESSION_INFO = 'dword SessionId;ptr WinStationName;uint State' Local $aResult = DllCall('wtsapi32.dll', 'int', 'WTSEnumerateSessionsW', 'ptr', 0, 'dword', 0, 'dword', 1, 'ptr*', 0, 'dword*', 0) If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "") ; https://docs.microsoft.com/en-us/windows/desktop/api/wtsapi32/ne-wtsapi32-_wts_connectstate_class Local $aConnectionState = StringSplit("Active,Connected,ConnectQuery,Shadow,Disconnected,Idle,Listen,Reset,Down,Init", ",", 2) Local $tInfo, $Offset = 0, $c = 0, $aReturn[$aResult[5] + 1][$e_UBound] ; $e_UBound is the last enumerator, just to determine the size of the array $aReturn[0][$e_SessionId] = "ID" $aReturn[0][$e_SessionName] = "SessionName" $aReturn[0][$e_StateInt] = "StateInt" $aReturn[0][$e_StateName] = "State" $aReturn[0][$e_UserName] = "UserName" $aReturn[0][$e_ClientName] = "ClientName" $aReturn[0][$e_ClientIp] = "ClientIp" $aReturn[0][$e_Domain] = "Domain" For $i = 1 To $aResult[5] $tInfo = DllStructCreate($tagWTS_SESSION_INFO, $aResult[4] + $Offset) $Offset += DllStructGetSize($tInfo) $c += 1 $aReturn[$c][$e_SessionId] = DllStructGetData($tInfo, 'SessionId') $aReturn[$c][$e_SessionName] = DllStructGetData(DllStructCreate('wchar[1024]', DllStructGetData($tInfo, 'WinStationName')), 1) $aReturn[$c][$e_StateInt] = DllStructGetData($tInfo, 'State') If UBound($aConnectionState) > $aReturn[$c][$e_StateInt] Then $aReturn[$c][$e_StateName] = $aConnectionState[$aReturn[$c][$e_StateInt]] $aReturn[$c][$e_UserName] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 5) ; WTSUserName $aReturn[$c][$e_ClientName] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 10) ; WTSClientName $aReturn[$c][$e_ClientIp] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 14) ; WTSClientAddress $aReturn[$c][$e_Domain] = _WTSQuerySessionInformation($aReturn[$c][$e_SessionId], 7) ; WTSDomainName $aReturn[0][$e_IsSelf_SessionId] = $c If $_Self_SessionId = $aReturn[$c][$e_SessionId] Then $aReturn[$c][$e_IsSelf_SessionId] = 1 Else $aReturn[$c][$e_IsSelf_SessionId] = 0 EndIf Next DllCall('wtsapi32.dll', 'none', 'WTSFreeMemory', 'ptr', $aResult[4]) Return $aReturn EndFunc ;==>ListUserSessions Func _WTSQuerySessionInformation($SessionId, $WTSInfoClass = 10, $iReturnAsIs = 0) ; mod. of https://www.autoitscript.com/forum/topic/134679-get-hostname-of-the-client-connected-to-the-terminalserver-session/ Local $aResult = DllCall("Wtsapi32.dll", "int", "WTSQuerySessionInformation", "Ptr", 0, "int", $SessionId, "int", $WTSInfoClass, "ptr*", 0, "dword*", 0) If @error Or $aResult[0] = 0 Then Return SetError(1, 0, "") Local $ip = DllStructGetData(DllStructCreate("byte[" & $aResult[5] & "]", $aResult[4]), 1) DllCall("Wtsapi32.dll", "int", "WTSFreeMemory", "ptr", $aResult[4]) If $iReturnAsIs Then Return $ip Switch $WTSInfoClass ; https://docs.microsoft.com/en-us/windows/desktop/api/wtsapi32/ns-wtsapi32-_wts_client_address Case 4 ; WTSSessionId Return Int('0x' & StringTrimRight(StringReverse($ip), 3)) Case 14 ; WTSClientAddress If Not (Int(StringLeft($ip, 4)) = 2) Then ; IPv4 $ip = "" Else $ip = Dec(StringMid($ip, 15, 2)) & '.' & Dec(StringMid($ip, 17, 2)) & '.' & Dec(StringMid($ip, 19, 2)) & '.' & Dec(StringMid($ip, 21, 2)) EndIf EndSwitch Return StringReplace(BinaryToString($ip), Chr(0), "") EndFunc ;==>_GetWTSClientName1 point -
Copying files from many folders to one folder
Earthshine reacted to Docfxit for a topic
I found an unviewable character after Pictures. I have removed it and it's working now. This is my entire script: #include <WinAPIFiles.au3> #include <File.au3> ; This script will copy all files from many folders in the $sFileFromPath to one folder in the $sFileToPath ; If it finds a duplicate file name it will add a number to the file name ; Global $sFileToPath = "C:\MyPictures" Global $sFileToPathSlash = $sFileToPath ;Global $sFileFromPath = @AppDataDir & "\Corel\Messages\540217727_100001\en\MessageCache1\Workflow\shared\Images" Global $sFileFromPath = @UserProfileDir & "\Pictures" MsgBox(0, "", "From file Path: " & $sFileFromPath & @CRLF & "At Line# = " & @ScriptLineNumber) Global $sExt = "jpg" Local $bStatus = FileSetAttrib($sFileToPath & "\*.*", "-RS") ; Time to start over with a new set of files Local $iFileExists = FileExists($sFileToPath) If Not $iFileExists Then DirCreate($sFileToPath) Else FileDelete($sFileToPath & "\*.*") EndIf If Not StringRegExp($sFileToPath, "\\\z") Then $sFileToPathSlash &= "\" ; Append missing '\' to $sFileToPath if needed MoveFiles($sFileFromPath, $sFileToPathSlash, $sExt) ;Protect the folder making it read only Local $bStatus = FileSetAttrib($sFileToPath & "\*.*", "+RS") Local $bStatus = FileSetAttrib($sFileToPath, "+RS") Exit Func MoveFiles($sFileFromPath, $sFileToPathSlash, $sExt = ".*") If Not StringRegExp($sFileFromPath, "\\\z") Then $sFileFromPath &= "\" ; Append missing '\' to $sFileFromPath if needed FileChangeDir($sFileFromPath) $hSearch = FileFindFirstFile("*.*") $hFile = FileFindNextFile($hSearch) While Not @error If @extended Then ; $hFile is a directory MoveFiles($sFileFromPath & $hFile, $sFileToPathSlash, $sExt) ; Scan the subdirectory Else ; $hFile is a file FileChangeDir($sFileFromPath) Global $sFileFrom = $sFileFromPath & $hFile Global $sFileTo = $sFileToPathSlash & $hFile $vResult = _SecureFileMove($sFileFrom, $sFileTo) ; Folder not created = C:\MyPictures Error pops up here at line 51 If $vResult == 0 Then ; 0 = error MsgBox(0, "", "Error copying file to: " & $sFileTo & @CRLF & "From file: " & $sFileFrom & @CRLF & "At Line# = " & @ScriptLineNumber & @CRLF & "$vResult = " & $vResult) Else ; on success the name of the moved file is returned ; MsgBox(0, "", "File successfully Copied to: " & $vResult) EndIf EndIf $hFile = FileFindNextFile($hSearch) WEnd FileClose($hSearch) EndFunc ;==>MoveFiles Func _SecureFileMove($sFileFrom, $sFileTo) Local $iIndex = 0, $sFileTemp, $iResult Local $sDrive, $sDir, $sFName, $sExt If FileExists($sFileTo) Then _PathSplit($sFileTo, $sDrive, $sDir, $sFName, $sExt) While 1 $iIndex = $iIndex + 1 $sFileTemp = $sDrive & $sDir & $sFName & "_" & $iIndex & $sExt If Not FileExists($sFileTemp) Then ExitLoop WEnd ; MsgBox(0, "", "Duplicate file found: " & $sFileTemp) $sFileTo = $sFileTemp EndIf $iResult = FileCopy($sFileFrom, $sFileTo) If $iResult = 1 Then Return $sFileTo Else Return 0 EndIf EndFunc ;==>_SecureFileMove Thanks for the help. Docfxit1 point -
cmd line to pull serial number from remote device
JayHawkfl reacted to FrancescoDiMuro for a topic
@JayHawkfl Happy to have helped. Have a good day1 point -
Copying files from many folders to one folder
Earthshine reacted to Docfxit for a topic
That's a good idea. I tried this code: Local $bStatus = FileSetAttrib($sFileToPath & "\*.*", "-R") ; Time to start over with a new set of files Local $iFileExists = FileExists($sFileToPath) If Not $iFileExists Then DirCreate($sFileToPath) Else FileDelete($sFileToPath & "\*.*") MsgBox(0, "", "Check the files in: " & $sFileToPath & @CRLF & "At Line# = " & @ScriptLineNumber) EndIf I have it working with this code. That solved the problem.1 point -
Copying files from many folders to one folder
Docfxit reacted to Earthshine for a topic
why not just delete the folders contents and continue to copy data to it? why delete the folder?1 point -
@youtuber I used .+ because I assumed that you have no file with the name "_stripped.au3" , but you can use .* as well If you remove parenthesis then you don't remove "_stripped.au3" from the filename Yes but it again doesn't allow to remove the filter from the filename. Let's say that using this option or not is left to the OPs choice1 point
-
Control Box - Buttons not detectable
derlin reacted to Earthshine for a topic
I suggest you look at FAQ 31 for UIAutomation to automate Windows 10 apps as they are XAML forms, and you cannot use standard autoit on them1 point -
Copying files from many folders to one folder
Earthshine reacted to FrancescoDiMuro for a topic
@Docfxit A bit "off-topic", but if the task is to copy some files from a source directory to a source directory, then use something like XCOPY command, from which you can set a lot of parameters for the copy process1 point -
Two ways to do it, basically: 1) write a script and use IE* function to automate the selection and grab data. 2) select MM/YYYY and select the table using your mouse, copy-paste in a text editor and save as .TSV file. I've done 2) for you up to 2019-12 in the attached file. This pedestrian but you just spend 5 minutes each year and that should work even if the web page structure changes over time. Decl.tsv1 point
-
Control Box - Buttons not detectable
derlin reacted to FrancescoDiMuro for a topic
Hi @derlin, and welcome to the AutoIt forums The control you are trying to automate is a TreeView control, so, you should be able to interact with it with _GUICtrlTreeView_* functions. Get the handle of the control using one of the information provided by the AutoItWinowInfo Tool (Name, ClassnameNN), and then use that handle with one of the _GUICtrlTreeView_* functions, which could easily bring a feedback about the interaction with the control (click the second element of the control, get the count, and so on). From there, if those functions helps you out, then just use them to do "whatever" you want. P.S.: always post your script so we can help you further1 point -
$RegExp = StringRegExp($search[$i], '(?i)(.+)_stripped.au3', 3)1 point
-
can you just put it in the filter? #include <File.au3> #include<Array.au3> $path = @ScriptDir $filter = "*_stripped.au3" $search = _FileListToArray($path, $filter) _ArrayDisplay($search)1 point
-
UIAutomation to detect controls that have repeated AutomationID and properties
RadicalKoncepts reacted to junkew for a topic
There is a uia.cfg where you can set this behavior from highlighting true/false [Global] Debug=false Debug.file=false Highlight=true AutoStartSUT=false If the file does not exist it falls back to true as default you could overrule it in your coding with _UIA_setVar("Global.Highlight", False) and to be complete for the other 2 _UIA_setVar("Global.Debug", True) _UIA_setVar("Global.Debug.File", True) _UIA_setVar("Global.Highlight", True)1 point -
How to get all controls in a window
RadicalKoncepts reacted to iLoveAU3 for a topic
#include "Array.au3" Opt("WinTitleMatchMode", 4) $aArray = _WinGetControls('[class:Shell_TrayWnd]') _ArrayDisplay($aArray) Func _WinGetControls($Title, $Text="") Local $WndControls, $aControls, $sLast="", $n=1 $WndControls = WinGetClassList($Title, $Text) $aControls = StringSplit($WndControls, @CRLF) Dim $aResult[$aControls[0]+1][2] For $i = 1 To $aControls[0] If $aControls[$i] <> "" Then If $sLast = $aControls[$i] Then $n+=1 Else $n=1 EndIf $aControls[$i] &= $n $sLast = StringTrimRight($aControls[$i],1) EndIf If $i < $aControls[0] Then $aResult[$i][0] = $aControls[$i] Else ; last item in array $aResult[$i][0] = WinGetTitle($Title) ; return WinTitle EndIf $aResult[$i][1] = ControlGetHandle($Title, $Text, $aControls[$i]) Next $aResult[0][0] = "ClassnameNN" $aResult[0][1] = "Handle" Return $aResult EndFunc this should do the trick1 point