jchd Posted September 17, 2020 Posted September 17, 2020 Simpler: ; Returns the string on the left side of a search string consisting of digits only ConsoleWrite(_StringGetDigitLeft("1234abcd5678") & @CRLF) ; Results in "1234" ConsoleWrite(_StringGetDigitLeft("abcd5678") & @CRLF) ; Results in "" ; Returns the string on the right side of a search string consisting of digits only ConsoleWrite(_StringGetDigitRight("1234abcd5678") & @CRLF) ; Results in "5678" ConsoleWrite(_StringGetDigitRight("1234abcd") & @CRLF) ; Results in "" Func _StringGetDigitLeft(Const ByRef $sString) ; Return String(Number($sString)) ; requires at least one leading digit Return StringRegExpReplace($sString, "^(?|(\d+)|())(.*$)", "$1") EndFunc Func _StringGetDigitRight(Const ByRef $sString) Return StringRegExpReplace($sString, "(.*?)(?|(\d+)|())$", "$2") EndFunc Exit 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
DonChunior Posted September 17, 2020 Posted September 17, 2020 1 hour ago, jchd said: Simpler That's a matter of opinion. 😉 I find my variant more comprehensible. TheDcoder, seadoggie01 and Exit 1 2
seadoggie01 Posted September 17, 2020 Posted September 17, 2020 There's a certain grace that comes with admitting you were wrong (or that someone did something better). Trust me, I've been there... too much. It happens a lot, don't worry about it. argumentum and pixelsearch 2 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
TheDcoder Posted September 18, 2020 Posted September 18, 2020 I agree with @DonChunior, their version uses StringIsDigit while @jchd's version uses RegEx, it is a matter of opinion which is simpler, not all people know or like RegEx DonChunior 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
T0ny Posted September 26, 2020 Posted September 26, 2020 (edited) Hi guys, I've spent a couple hours today to understand socks5 proxy and tried to implement connecting to an external proxy through autoit. My goal is to add this function to my IRC client. It's all about learning isn't it ?!? I've got the authentication part working, and I am sending the snippet here thinking it might interest somebody Have fun! Next step, I will be testing some requests to IRC servers, I am also interested into adding SSL support !!! -el tonio ; Socks5 proxy server authentication using the username/password method (0x02) expandcollapse popup; Pure AutoIt 3, Authentication to Socks5 proxy server using the username/password method Global Const $AuthNumberOfAuthMethodsSupported = 2 Global Const $AuthMethodNoAuthenticationRequired = 0x00 Global Const $AuthMethodUsernamePassword = 0x02 Local $ProxyHost = "your Socks5 server hostname"; Local $ProxyPort = "your Socks5 server port"; Local $Username = "User name" Local $Password = "Password" TCPStartup() Opt("TCPTimeout", 5000) ; 1. Connect to Proxy Local $socket $socket = TCPConnect(TCPNameToIP($ProxyHost),$ProxyPort) If $socket > 0 Then ConsoleWrite($socket & " Connected..." & @CRLF) ; 2. GREETING the server (Or telling it what Auth Method you support) Local $sReq = Chr("0x05") _ ; Socks version 5 & Chr("2") _ ; 2 auth methods supported & Chr($AuthMethodNoAuthenticationRequired) _ ; No Auth Required method & Chr($AuthMethodUsernamePassword) ; Username/Password method ConsoleWrite("$sReq : " & $sReq & @CRLF) TCPSend($socket, $sReq) Local $sBuff ; Waiting for the server to reply While 1 $sBuff = TCPRecv($socket,6,1) If @error Then ExitLoop If StringLen($sBuff) > 0 Then ExitLoop Sleep(100) WEnd ConsoleWrite(@CRLF & "! Reply: " & $sBuff & @CRLF) If StringRight($sBuff, 2) = "02" Then ; Server chose the username/password method which is GREAT! ; 3. Perform Authentification $sReq = "0x01" _ & StringMid(Binary(StringLen($Username)), 3, 2) _ & StringMid(StringToBinary($Username), 3) _ & StringMid(Binary(StringLen($Password)), 3, 2) _ & StringMid(StringToBinary($Password), 3) ConsoleWrite("$sReq : " & $sReq & @CRLF) TCPSend($socket, $sReq) ; Wait for the Reply ConsoleWrite("Waiting for the reply ... " & @CRLF) While 1 $sBuff = TCPRecv($socket,10,1) If @error Then ExitLoop If StringLen($sBuff) > 0 Then ExitLoop Sleep(100) WEnd ConsoleWrite(@CRLF & "! Reply: " & $sBuff & @CRLF) If StringRight($sBuff, 2) = "00" Then ; Authentication successful ConsoleWrite("Authenticated..." & @CRLF) While 1 ; Now you can work on requests to whatever, from this point the request is similar to Socks4 Sleep(10) WEnd Else ; Authentication failed EndIf Else ; In case the server do not discuss by the book!! EndIf Else ; Connecting error ConsoleWrite("Connecting error " & " - " & @error & @CRLF) EndIf TCPCloseSocket($socket) TCPShutdown() Exit Was helpful to me: https://en.wikipedia.org/wiki/SOCKS#SOCKS5 https://blog.zhaytam.com/2019/11/15/socks5-a-net-core-implementation-from-scratch/ Edited September 28, 2020 by T0ny TheDcoder 1
abberration Posted September 29, 2020 Posted September 29, 2020 (edited) I found myself needing to search different parts of a large array and did not need all the results from _ArrayFindAll, so I wrote a similar function, which I call _ArrayFindRanges. Instead of $iStart and $iEnd, you use ranges separated by semi-colons (ex: "2-5;8-12;18-30;42-50"). I tested various aspects and I am not finding any flaws yet. If anyone has suggestions to make it better or more efficient, I would love to hear from you. Hope you guys like it! 🤠 Update! (10-6-2020) I took seadoggie01's suggestion to only ReDim once (Thx, seadoggie01!). Also, while integrating this function into a script, I discovered I was forcing the $iForward parameter to be forward searching only in the _ArraySearch call. I fixed that as well. I changed where Default is passed to $iRanges will search the entire array (this makes it act like _ArrayFindAll). Lastly, I discovered if you entered nothing or incorrect data for $iRanges, it will crash your program. I included a check that will return an error code instead of going through the loops, letting you know you have no matches because you passed improper data for $iRanges. I just realized I need to put in more checks to make sure only numbers are passed and possible error codes - I will work on this. The syntax should be the same except for not receiving errors for having the correct number of parameters. _ArraySearch uses 9 parameters and my function uses 8 parameters (the $iStart and $iEnd are replaced with $iRanges). It's working efficiently and perfectly in my script. I will work on more error checking and update when I have completed it. Updated code: expandcollapse popup#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 #include <array.au3> ; Examples Local $aValues[20] = ["", "", "you", "you", "you", "me", "me", "", "", "you", "me", "", "", "me", "you", "me", "", "", ""] ; 1D array Local $aValues2[2][4] = [["peter", "paul", "mary", "paul"], ["peter", "mary", "mary", "peter"]] ; 2D array Local $test, $testErrorNotArray = "wow" $test = _ArrayFindRanges($aValues, "Me", "2-7;12-18", 0, 0, 0, False) ; test 1D array If @error Then MsgBox(0, "", @error) _ArrayDisplay($test) $test = _ArrayFindRanges($aValues2, "mary", "1-4", 0, 0, 1, True) ; test 2D array choosing to search columns instead of rows If @error Then MsgBox(0, "", @error) _ArrayDisplay($test) $test = _ArrayFindRanges($aValues2, "joe", "1-4", 0, 0, 1, True) ; test 2D array, testing @error result If @error Then MsgBox(0, "", @error) _ArrayDisplay($test) $test = _ArrayFindRanges($testErrorNotArray, "joe", "1-4", 0, 0, 1, True) ; test 2D array, testing a different @error result If @error Then MsgBox(0, "", @error) _ArrayDisplay($test) #cs Syntax: _ArrayFindRanges ( Const ByRef $aArray, $iRanges ("num1-num2;num3-num4;num5-num6"), [, $iCase = 0 [, $iCompare = 0 [, $iSubItem = 0 [, $bRow = False]]]]]] ) Note: $iRanges must enclose all the number ranges in quotes and separate the various ranges by semi-colons. Success: An array of all index numbers in array containing $vValue. Failure: Sets the @error flag to non-zero (see _ArraySearch() description for @error). Remarks The values of $iCompare can not be combined together. #ce ; #FUNCTION# ==================================================================================================================== ; Title .........: ArrayFindRanges ; AutoIt Version : 3.3.14.2 ; Description ...: Search ranges of an array (similar to _ArrayFindAll) ; Author ........: abberration ; Thanks ........: seadoggie01 for improvement suggestions ; =============================================================================================================================== Func _ArrayFindRanges(Const ByRef $aArray, $vValue, $iRanges, $iCase = 0, $iCompare = 0, $iForward = 1, $iSubItem = 0, $bRow = False) Local $iIndex = 1, $avResult[UBound($aArray)], $aRangeSplit, $aValuesSplit, $iResult If $iRanges = Default Then $iRanges = "1-" & UBound($aArray) If $iCompare = Default Then $iCompare = 0 If $iSubItem = Default Then $iSubItem = 0 If $bRow = Default Then $bRow = False $aRangeSplit = StringSplit($iRanges, ";") If $aRangeSplit[1] = "" Then Return SetError(@error, 0, -1) Else For $i = 1 To $aRangeSplit[0] $aValuesSplit = StringSplit($aRangeSplit[$i], "-", 2) For $j = $aValuesSplit[0] To $aValuesSplit[1] $iResult = _ArraySearch($aArray, $vValue, $j, $aValuesSplit[1], $iCase, $iCompare, $iForward, $iSubItem, $bRow) $j = $iResult If $iResult = -1 Then ExitLoop $avResult[$iIndex - 1] = $iResult $iIndex += 1 Next Next EndIf If $iIndex = 1 Then Return SetError(@error, 0, -1) ReDim $avResult[$iIndex - 1] Return $avResult EndFunc ;==>_ArrayFindRanges Edited October 6, 2020 by abberration Last update for today. Included thanks to seadoggie01 in function header and a couple grammar fixes. Easy MP3 | Software Installer | Password Manager
seadoggie01 Posted September 30, 2020 Posted September 30, 2020 My two three cents: (whatever they're worth ) 1. Arrays resizing (ReDim) is a costly process. To speed things up, don't do it every time you find a match. Instead, either calculate the largest number of possible results up front and then size your array, or start with an array of say 100 and add as needed. At the very least, right now you're resizing your array after every match and at the end. Instead, just resize it when you get a match (start with $iIndex = 0 and resize before adding the value to the array). 2. I'm not sure (because I haven't tested), but I would think that calling _ArrayFindAll once instead of _ArraySearch many times would be more efficient. 3. I think that an invalid string passed in $iRanges (shouldn't that be $sRanges?) will break your function... you aren't checking the @error value of StringSplit. And yeah, GIGO, but I try to handle all the garbage I can find That said, as long as it works for you, who cares?! I probably would've started with the results from _ArrayFindAll and chucked out all the results I didn't need, but that's probably wasteful. It's a good function if you have a need for it! TheDcoder and abberration 1 1 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
abberration Posted September 30, 2020 Posted September 30, 2020 Hi, seadoggie01, You make a great point about ReDim. I will look at the code soon and try to rework it to only ReDim once. _ArrayFindAll is what I used to model my function. It uses _ArraySearch for it's results, so using _ArrayFindAll should not be any faster. You are correct, I should have done more error checking. Before I put in the one @error, when I passed bad info, it only returned an empty array. When I put in the one @error, it seemed to return the correct error handle. But I do need to do more testing in this area. I got it working and was very tired, so I just posted it. I will continue working on it. I think it could be a very useful addition when it's perfected. I have already determined that declaring the default value of $iRanges is useless as it is. I need to work on that. Thank you for your suggestions. I will use them to improve the script. seadoggie01 1 Easy MP3 | Software Installer | Password Manager
DonChunior Posted October 15, 2020 Posted October 15, 2020 (edited) On 9/17/2020 at 1:55 PM, jchd said: Simpler: ; Returns the string on the left side of a search string consisting of digits only ConsoleWrite(_StringGetDigitLeft("1234abcd5678") & @CRLF) ; Results in "1234" ConsoleWrite(_StringGetDigitLeft("abcd5678") & @CRLF) ; Results in "" ; Returns the string on the right side of a search string consisting of digits only ConsoleWrite(_StringGetDigitRight("1234abcd5678") & @CRLF) ; Results in "5678" ConsoleWrite(_StringGetDigitRight("1234abcd") & @CRLF) ; Results in "" Func _StringGetDigitLeft(Const ByRef $sString) ; Return String(Number($sString)) ; requires at least one leading digit Return StringRegExpReplace($sString, "^(?|(\d+)|())(.*$)", "$1") EndFunc Func _StringGetDigitRight(Const ByRef $sString) Return StringRegExpReplace($sString, "(.*?)(?|(\d+)|())$", "$2") EndFunc Hello @jchd, I did a small benchmark to compare the performance of our _StringGetDigitLeft and _StringGetDigitRight functions. For this purpose I have used the following password list: https://github.com/danielmiessler/SecLists/blob/master/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt The code of my benchmark was as follows: Local $asPasswordList = 0 Local $hTimer = 0 Local $fDiff = 0.0 $asPasswordList = FileReadToArray("10-million-password-list-top-1000000.txt") $hTimer = TimerInit() For $sPassword In $asPasswordList _StringGetDigitLeft($sPassword) ;~ _StringGetDigitRight($sPassword) Next $fDiff = TimerDiff($hTimer) ConsoleWrite($fDiff & " ms" & @CRLF) It turned out that your functions based on regular expressions were each over 50% faster! So I have to give you credit for the fact that your variants would be technically preferable in any case. 🏆👏 Edited October 15, 2020 by DonChunior
jchd Posted October 15, 2020 Posted October 15, 2020 Well, it's not always the case that regexps are the fastest way to perform a given task. However once one takes the pain to reasonably master their "strange" syntax and specific features, they can prove elegant and unvaluable in a large number of use cases. Of course their power tends to make overuse tempting. This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)
TheDcoder Posted October 16, 2020 Posted October 16, 2020 18 hours ago, DonChunior said: It turned out that your functions based on regular expressions were each over 50% faster! And I'd like to mention that it is probably because AutoIt has a lot of overhead in string processing and the interpreter itself is a bit slow. Compare that to an optimized RegEx engine written in C(++) and it is clear why it is faster, despite being logically a more complex operation Speed isn't everything, and AutoIt isn't that fast really, so unless you are processing many strings in bulk, it is okay to use whatever you prefer, it won't make a significant difference in operation. DonChunior 1 EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time) DcodingTheWeb Forum - Follow for updates and Join for discussion
DonChunior Posted October 16, 2020 Posted October 16, 2020 4 hours ago, TheDcoder said: And I'd like to mention that it is probably because AutoIt has a lot of overhead in string processing and the interpreter itself is a bit slow. Compare that to an optimized RegEx engine written in C(++) and it is clear why it is faster, despite being logically a more complex operation Speed isn't everything, and AutoIt isn't that fast really, so unless you are processing many strings in bulk, it is okay to use whatever you prefer, it won't make a significant difference in operation. That my version would be easier to understand (for me) was admittedly a subjective opinion. I just wanted to look at the topic more objectively, hence my benchmark.
wolflake Posted December 14, 2020 Posted December 14, 2020 Code to a String: This is a tool to modify code from the clipboard to be pasted as code that can let one program write a file and run the code from that file. I had written an #include file that needed to run a separate program to make a window, but I didn't want to hard code the location of the include file or the window. So I decided to carry the window program within the main program. To do this I wrote the separate program to make the window, then copied it to the clipboard and ran the program below that takes the clipboard and reformats it into code that when run puts that code into a string. I copy that code into the main program then when I need to run the window program the main program calls the function that takes the string writes it to a file and runs the file. ;Make a $sString of code to include in prgm ;Put the code on the clipboard run the prg and paste the string building code in your prg #include <array.au3> Global $q = Chr(39) $aStr = StringSplit(clipget(),@CRLF,3) ;ArrayFromClip for $i = 0 to UBound($aStr) - 1 if $i = 0 then $aStr[$i] = "$sString = " & $q & $aStr[$i] & $q & "& @CRLF" Else $aStr[$i] = "$sString &= " & $q & $aStr[$i] & $q & "& @CRLF" EndIf Next _ArrayToClip($aStr,@CRLF) So copying the program above to the clipboard and running it would produce... $sString = ';Make a $sString of code to include in prgm'& @CRLF $sString &= ';Put the code on the clipboard run the prg and paste the string building code in your prg'& @CRLF $sString &= '#include <array.au3>'& @CRLF $sString &= 'Global $q = Chr(39)'& @CRLF $sString &= '$aStr = StringSplit(clipget(),@CRLF,3) ;ArrayFromClip'& @CRLF $sString &= 'for $i = 0 to UBound($aStr) - 1'& @CRLF $sString &= ' if $i = 0 then'& @CRLF $sString &= ' $aStr[$i] = "$sString = " & $q & $aStr[$i] & $q & "& @CRLF"'& @CRLF $sString &= ' Else'& @CRLF $sString &= ' $aStr[$i] = "$sString &= " & $q & $aStr[$i] & $q & "& @CRLF"'& @CRLF $sString &= ' EndIf'& @CRLF $sString &= 'Next'& @CRLF $sString &= '_ArrayToClip($aStr,@CRLF)'& @CRLF $sString &= ''& @CRLF Adding: FileWrite(@workingdir & "filename.au3",$sString) ShellExecute(@workingdir & "filename.au3") would write it and run it. You could add code to erase the file as part of $GUI_EVENT_CLOSE or just before the codes exits with OnAutoItExitRegister. That way you don't end up with multiple copies if you run in different folders. I hope this is understandable but I happy to answer a question if it isn't. Draygoes 1
seadoggie01 Posted December 17, 2020 Posted December 17, 2020 (edited) While I hate this kind of file, I recently had to re-write an Excel VBA script that wrote the worksheet to a fixed width format file. It isn't perfect, but this is what I have so far: expandcollapse popup; #FUNCTION# ==================================================================================================================== ; Name ..........: _Export_FixedWidth ; Description ...: Exports an array to a file using a fixed width format ; Syntax ........: _Export_FixedWidth($avData, $aiWidth, $aiPrecision, $sFile[, $sNewLine = Default]) ; Parameters ....: $avData - a 2D array of variants. ; $aiWidth - a 1D array of integers. ; $aiPrecision - a 1D array of integers. Default copies $aiWidth. ; $sFile - full file path to save as or a file handle. ; $sNewLine - [optional] newline. Default is @CRLF. ; Return values .: Success - True ; Failure - False and sets @error: ; |1 - $avData isn't a 2D array ; |2 - $avData has more columns than (@extended) 1 - $aiWidth or 2 - $aiPrecision ; |3 - Unable to write data to $sFile ; Author ........: Seadoggie01 ; Modified ......: December 17, 2020 ; Remarks .......: $aiWidth's and $aiPrecision's sizes must match $avData's column count. ; If $sFile is a handle, it will not be closed ; Data is right aligned; set $aiWidth's value to negative to right align data. ; +$aiPrecision uses the absolute value (helpful if $aiPrecision = $aiWidth) ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func _Export_FixedWidth($avData, $aiWidth, $aiPrecision, $sFile, $sNewLine = Default) If IsKeyword($aiPrecision) Then $aiPrecision = $aiWidth If IsKeyword($sNewLine) Then $sNewLine = @CRLF ; Ensure 2D array If UBound($avData, 0) <> 2 Then Return SetError(1, 0, False) ; Check sizes of the arrays If UBound($aiWidth) <> UBound($avData, 2) Then Return SetError(2, 1, False) If UBound($aiPrecision) <> UBound($avData, 2) Then Return SetError(2, 2, False) Local $sExportText ; For each row For $iRow = 0 To UBound($avData) - 1 ; For each column For $iColumn = 0 To UBound($avData, 2) - 1 ; Format the data as a string using the width and precision assigned by the user $sExportText &= StringFormat("%" & (-1 * $aiWidth[$iColumn]) & "." & Abs($aiPrecision[$iColumn]) & "s", $avData[$iRow][$iColumn]) Next $sExportText &= $sNewLine Next If Not FileWrite($sFile, $sExportText) Then Return SetError(3, 0, False) Return True EndFunc As the VBA was looping through each cell, reading it (and the precision), and writing it to file, it was taking upwards of 10 minutes as the worksheet was 72 columns x 15367 rows (~1.1 M cells). I'm very impatient and this was just too much. Now it takes less than a second to write the data I lied, I needed more error checking. 🤦♂️ However, 24 seconds is still much better Edited December 17, 2020 by seadoggie01 robertocm and BigDaddyO 1 1 All my code provided is Public Domain... but it may not work. Use it, change it, break it, whatever you want. Spoiler My Humble Contributions:Personal Function Documentation - A personal HelpFile for your functionsAcro.au3 UDF - Automating Acrobat ProToDo Finder - Find #ToDo: lines in your scriptsUI-SimpleWrappers UDF - Use UI Automation more Simply-erKeePass UDF - Automate KeePass, a password managerInputBoxes - Simple Input boxes for various variable types
CarlD Posted January 11, 2021 Posted January 11, 2021 (edited) Text in, AutoIt string concatenation out (clipboard in and out). Can choose double or single quote character for output by editing script. Args (can be combined): W - Chars 128+ are encoded with AscW() V - Strings in the form "$$string" are concatenated as AutoIt variables. Useful for generating code for a child script that uses values established in the parent script. For example: Input string 1: Const $sChildString = $sParentString Output with (or without) Arg "V": "Const $sChildString = $sParentString" & @CRLF Input string 2 (note double "$$"): Const $sChildString = "$$sParentString" Output with Arg "V": "Const $sChildString = """ & $sParentString & """ & @CRLF Updated script: expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #Au3Stripper_Parameters=/so #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d #AutoIt3Wrapper_AU3Check_Stop_OnWarning=y #AutoIt3Wrapper_Change2CUI=n #AutoIt3Wrapper_Outfile_type=a3x #AutoIt3Wrapper_Run_Au3Stripper=y #AutoIt3Wrapper_UseUpx=n #AutoIt3Wrapper_UseX64=n #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ; ; Text2Au3.au3 ; Text to AutoIt string concatenation ; Clipboard in + out ; CLD rev. 1/18/2021 ; ; Quote char for output code Global $sQChar = '"' ; double quote (") ; Global $sQChar = "'" ; single quote (') ; Global $sIn = ClipGet() If Not $sIn Then Exit Global $sArg = "" If $CmdLine[0] > 0 Then ; Arg "V" converts $$variable to $variable ; Arg "W" encodes Ascii 128+ For $a = 1 To $CmdLine[0] $sArg &= $CmdLine[$a] Next EndIf Global $aIn = StringSplit($sIn, "") Global $sCloseQuo = $sQChar & " & " Global $bTx = 0, $sOut = "" Global $sVarChars = "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" For $i = 1 To $aIn[0] Select Case $aIn[$i] = $sQChar $sOut &= $sQChar & $sQChar Case $aIn[$i] = Chr(13) PutCloseQuo() $sOut &= "@CR" If $i < $aIn[0] And $aIn[$i + 1] = @LF Then $sOut &= "LF" $i += 1 EndIf $sOut &= " & " Case $aIn[$i] = Chr(10) PutCloseQuo() $sOut &= "@LF & " Case Asc($aIn[$i]) < 32 PutCloseQuo() $sOut &= "Chr(" & Asc($aIn[$i]) & ") & " Case AscW($aIn[$i]) > 127 If StringInStr($sArg, "W") Then PutCloseQuo() $sOut &= "ChrW(" & AscW($aIn[$i]) & ") & " Else ContinueCase EndIf Case ( StringInStr($sArg, "V") And $aIn[$i] = "$" And _ $i < $aIn[0] - 1 ) If $aIn[$i + 1] = "$" And StringInStr($sVarChars, $aIn[$i + 2]) Then PutCloseQuo() $i += 1 Do $sOut &= $aIn[$i] $i += 1 If $i > $aIn[0] Then ExitLoop 2 Until StringInStr($sVarChars, $aIn[$i]) = 0 $i -= 1 $sOut &= " & " $bTx = 1 Else ContinueCase EndIf Case Else If $bTx = 0 And StringLen($sOut) > 0 Then $sOut &= $sQChar $bTx = 1 If Not $sOut Then $sOut = $sQChar $sOut &= $aIn[$i] EndSelect Next If StringInStr(StringRight($sOut, 3), "&") Then $sOut = StringTrimRight($sOut, 3) If $bTx = 1 Then $sOut &= $sQChar ClipPut($sOut & @CRLF) Exit MsgBox(0, @ScriptName, "Ctrl-V pastes output") Func PutCloseQuo() If $bTx = 1 And StringLen($sOut) > 0 Then $sOut &= $sCloseQuo $bTx = 0 Return EndFunc ;==>PutCloseQuo Edited January 18, 2021 by CarlD Update
CarlD Posted February 5, 2021 Posted February 5, 2021 (edited) Function that returns the singular or plural, depending on the number. ; Example 1 $sMessage = _ @HOUR & " " & _OneMany("hour", @HOUR) & ", " & _ @MIN & " " & _OneMany("MINUTE", @MIN) & ", " & _ @SEC & " " & _OneMany("second", @SEC) MsgBox(0, @ScriptName, $sMessage) ;Example 2 MsgBox(0, @ScriptName, "He has five " & _OneMany("child", 5, "children") & ".") Func _OneMany($sSingular, $iCount, $sPlural = "") ; Returns singular or plural depending on count ; Plural appends S to singular unless $sPlural is supplied Local $sEss = "s" If StringUpper($sSingular) == $sSingular Then $sEss = "S" If Not $sPlural Then $sPlural = $sSingular & $sEss If Abs($iCount) = 1 Then Return $sSingular Else Return $sPlural EndIf EndFunc ;==>_OneMany Edited February 5, 2021 by CarlD
argumentum Posted March 21, 2021 Posted March 21, 2021 (edited) expandcollapse popup#include-once ;~ #include <AutoItConstants.au3> ; needed For $STDERR_CHILD & $STDOUT_CHILD Global $__g_RunWaitEx_sWorkingDir = @TempDir Global $__g_RunWaitEx_iShowFlag = @SW_HIDE Global $__g_RunWaitEx_iOptFlag = 6 ; ; "BitOR($STDERR_CHILD, $STDOUT_CHILD) = 6" Global $__g_RunWaitEx_msTimeout = 0 ; these helper functions return the set values, or sets the values if provided with one. Func _RunWaitEx_WorkingDir($val = Default) If $val <> Default Then $__g_RunWaitEx_sWorkingDir = String($val) Return $__g_RunWaitEx_sWorkingDir EndFunc ;==>_RunWaitEx_WorkingDir Func _RunWaitEx_ShowFlag($val = Default) If $val <> Default Then $__g_RunWaitEx_iShowFlag = Int($val) Return $__g_RunWaitEx_iShowFlag EndFunc ;==>_RunWaitEx_ShowFlag Func _RunWaitEx_OptFlag($val = Default) If $val <> Default Then $__g_RunWaitEx_iOptFlag = Int($val) Return $__g_RunWaitEx_iOptFlag EndFunc ;==>_RunWaitEx_ShowFlag Func _RunWaitEx_Timeout($val = Default) If $val <> Default Then $__g_RunWaitEx_msTimeout = Int($val) Return $__g_RunWaitEx_msTimeout EndFunc ;==>_RunWaitEx_Timeout ; ..say you'd like to change a default due to circumstance ;~ If Not @Compiled Then _RunWaitEx_ShowFlag(@SW_SHOW) ; this example is to showcase the errorlevel/exitcode as the @extended value. Exit ConsoleWrite('--- Text >' & _RunWaitEx("dir /.ThisWillFail") & _ '--- @error >' & @error & @CRLF & _ ; timeout ? '--- exitcode >' & @extended & @CRLF) ;RunWait: Runs an external program and pauses the script execution until the program finishes, returning the exit code of the program that was run. ;_RunWaitEx: Same as RunWait() but also returns the output text and has an optional timeout. Func _RunWaitEx($sCommand, $sWorkingDir = Default, $iShowFlag = Default, $iOptFlag = Default, $msTimeout = Default) ; https://www.autoitscript.com/forum/index.php?showtopic=139260&view=findpost&p=1478119 ; ------------------- GetExitCodeProcess portion Switch $sWorkingDir Case "/OpenProcess" Local $hPID_HANDLE = DllCall('kernel32.dll', 'ptr', 'OpenProcess', 'int', 0x400, 'int', 0, 'int', $sCommand) If Not @error Then Return $hPID_HANDLE Return SetError(1, 0, 0) Case "/GetExitCodeProcess" Local $v_Placeholder, $aRet = DllCall('kernel32.dll', 'ptr', 'GetExitCodeProcess', 'ptr', $sCommand[0], 'int*', $v_Placeholder) If Not @error And UBound($aRet) > 2 Then Return $aRet[2] Return SetError(1, 0, 0) Case "/CloseHandle" DllCall('kernel32.dll', 'ptr', 'CloseHandle', 'ptr', $sCommand) If Not @error Then Return 1 Return 0 EndSwitch ; ------------------- set defaults If $sWorkingDir = Default Then $sWorkingDir = _RunWaitEx_WorkingDir() ; @TempDir If $iShowFlag = Default Then $iShowFlag = _RunWaitEx_ShowFlag() ; @SW_HIDE If $iOptFlag = Default Then $iOptFlag = _RunWaitEx_OptFlag() ; "BitOR($STDERR_CHILD, $STDOUT_CHILD) = 6" If $msTimeout = Default Then $msTimeout = _RunWaitEx_Timeout() ; ( 0 ms. = OFF ) in case the process takes longer than expected ; ------------------- Run() Local $iPID = Run(@ComSpec & " /c " & $sCommand, $sWorkingDir, $iShowFlag, $iOptFlag) If @error Or $iPID = 0 Then Return SetError(@error + 100, 0, "") Local $iExitCode = 0, $hPID_HANDLE = _RunWaitEx($iPID, "/OpenProcess") Local $hTimer = TimerInit(), $sOutput = "" While 1 $sOutput &= StdoutRead($iPID) If @error Then ExitLoop If $msTimeout And TimerDiff($hTimer) > $msTimeout Then ExitLoop Sleep(1) WEnd While 1 $sOutput &= StderrRead($iPID) If @error Then ExitLoop If $msTimeout And TimerDiff($hTimer) > $msTimeout Then ExitLoop Sleep(1) WEnd If $hPID_HANDLE <> 0 Then $iExitCode = _RunWaitEx($hPID_HANDLE, "/GetExitCodeProcess") If $iExitCode = 259 Then $iExitCode = 100000 + $iPID ; ...process not done, should not close handle. Else ; ...the PID will be the @extended - 100000 _RunWaitEx($hPID_HANDLE, "/CloseHandle") EndIf EndIf Return SetError($msTimeout And TimerDiff($hTimer) > $msTimeout ? 200 : 0, $iExitCode, $sOutput) EndFunc ;==>_RunWaitEx I bet there are examples of this but I liked this "All In One". 2021.04.03: Added helper functions to Set or Get default values. 2021.06.25: Added OptFlag() to set/change default ( does script break from prior version ) Edited June 25, 2021 by argumentum better code Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted April 7, 2021 Posted April 7, 2021 Center GUI on Monitor based on mouse position #include <AutoItConstants.au3> #include <GUIConstants.au3> #include <WinAPIGdi.au3> Func GuiCenterOnMonitorFromMousePosition($hForm, $sText = "") Local $aData, $hMonitor, $tPos = _WinAPI_GetMousePos() If Not @error Then $hMonitor = _WinAPI_MonitorFromPoint($tPos) If Not @error Then $aData = _WinAPI_GetMonitorInfo($hMonitor) If @error Then Return SetError(1, -1, 1) Local $iWinState = WinGetState($hForm, $sText) If @error Then Return SetError(2, $aData[2], 2) If BitAND($iWinState, $WIN_STATE_MINIMIZED) Or _ BitAND($iWinState, $WIN_STATE_MAXIMIZED) Then WinSetState($hForm, $sText, @SW_RESTORE) Local $aWinPos = WinGetPos($hForm, $sText) If @error Then Return SetError(3, $aData[2], 3) WinMove($hForm, _ $sText, _ Int((($aData[0].Right - $aData[0].Left - $aWinPos[2]) / 2) + $aData[0].Left), _ Int((($aData[0].Bottom - $aData[0].Top - $aWinPos[3]) / 2) + $aData[0].Top)) If @error Then Return SetError(4, $aData[2], 4) Return SetError(0, $aData[2], 0) EndFunc ;==>GuiCenterOnMonitorFromMousePosition Example() Func Example() Local $hGUI = GUICreate("GuiCenterOnMonitorFromMousePosition example", 600, 200) GuiCenterOnMonitorFromMousePosition($hGUI) GUICtrlCreateLabel("Primary display monitor = " & @extended, 20, 20, 160, 21) GUISetState() While GUIGetMsg() <> $GUI_EVENT_CLOSE WEnd GUIDelete() EndFunc ;==>Example DKiehl and Draygoes 1 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
argumentum Posted August 16, 2021 Posted August 16, 2021 I needed _DateDiff() to include milliseconds. ConsoleWrite('>>> ' & _DateDiffMs('2021/08/16 13:25:08.727', '2021/08/16 13:25:08.729') & @CRLF) Func _DateDiffMs($sDate1st, $sDate2nd) Local $iDate1st, $aDate1st = StringSplit($sDate1st, ".") ReDim $aDate1st[3] Local $iDate2nd, $aDate2nd = StringSplit($sDate2nd, ".") ReDim $aDate2nd[3] Local $iDate1st = _DateDiff('s', '1970/01/01 00:00:00', $aDate1st[1]) Local $iDate2nd = _DateDiff('s', '1970/01/01 00:00:00', $aDate2nd[1]) $iDate1st &= "000" $iDate2nd &= "000" $iDate1st += Int($aDate1st[2]) $iDate2nd += Int($aDate2nd[2]) Return ( $iDate2nd - $iDate1st ) / 1000 EndFunc CarlD, TheDcoder and Exit 2 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
CarlD Posted September 22, 2021 Posted September 22, 2021 (edited) Func _DateDiffWords uses _DateDiff and _DateAdd to report difference between two dates in words (also uses my Func _OneMany) expandcollapse popup#include <Date.au3> #include <MsgBoxConstants.au3> #AutoIt3Wrapper_AU3Check_Parameters=-w 3 -w 4 -w 5 -w 6 -d ; CarlD rev. 2021-09-25 Global $sDate1 = "2199/12/31 23:59:59"; later date Global $sDate2 = "1900/01/01 00:00:01"; earlier date (default = now) MsgBox( $MB_SYSTEMMODAL, @ScriptName, "Difference is:" & @LF & _DateDiffWords($sDate1) ); $sDate2 Func _DateDiffWords($date1, $date2 = @YEAR & "/" & @MON & "/" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC) ; Reports difference between two dates in words ; #include <Date.au3> ; $date1 = YYYY/MM/DD[ hh:mm[:ss]] Local $sDiffOut = "" Local $sYear = "year", $sMon = "month", $sWeek = "week", $sDay = "day" Local $sHour = "hour", $sMin = "minute", $sSec = "second" Local $sAnd = "and" Local $Y, $M, $W, $D, $H, $N, $S; _DateDiff types $Y = _DateDiff("Y", $date2, $date1) If $Y Then $sDiffOut = $Y & " " & _OneMany($sYear, $Y) $date1 = _DateAdd("Y", -1 * $Y, $date1) EndIf $M = _DateDiff("M", $date2, $date1) If $M Then If $sDiffOut Then $sDiffOut &= ", " $sDiffOut &= $M & " " & _OneMany($sMon, $M) $date1 = _DateAdd("M", -1 * $M, $date1) EndIf $W = _DateDiff("W", $date2, $date1) If $W Then If $sDiffOut Then $sDiffOut &= ", " $sDiffOut &= $W & " " & _OneMany($sWeek, $W) $date1 = _DateAdd("W", -1 * $W, $date1) EndIf $D = _DateDiff("D", $date2, $date1) If $D Then If $sDiffOut Then $sDiffOut &= ", " $sDiffOut &= $D & " " & _OneMany($sDay, $D) $date1 = _DateAdd("D", -1 * $D, $date1) EndIf $H = _DateDiff("H", $date2, $date1) If $H Then If $sDiffOut Then $sDiffOut &= ", " $sDiffOut &= $H & " " & _OneMany($sHour, $H) $date1 = _DateAdd("H", -1 * $H, $date1) EndIf $N = _DateDiff("N", $date2, $date1) If $N Then If $sDiffOut Then $sDiffOut &= ", " $sDiffOut &= $N & " " & _OneMany($sMin, $N) $date1 = _DateAdd("N", -1 * $N, $date1) EndIf $S = _DateDiff("S", $date2, $date1) If $S Then If $sDiffOut Then $sDiffOut &= " " & $sAnd & " " $sDiffOut &= $S & " " & _OneMany($sSec, $S) EndIf Return $sDiffOut EndFunc ;==>_DateDiffWords Func _OneMany($sSingular, $iCount, $sPlural = "") ; Returns singular or plural depending on count ; Plural appends S to singular (ES if it ends in S) ; unless $sPlural is supplied Local $sEss = "s" If StringRight($sSingular, 1) = "s" Then $sEss = "es" If StringUpper($sSingular) == $sSingular Then $sEss = StringUpper($sEss) If Not $sPlural Then $sPlural = $sSingular & $sEss If Abs($iCount) = 1 Then Return $sSingular Else Return $sPlural EndIf EndFunc ;==>_OneMany Edited September 25, 2021 by CarlD Update robertocm 1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now