If I have many calls to HotKeySet pointing to the same function, how I know which hotkey called it?
You can use the #HotKeyPressed variable.
for example:
$char = 0
while $char < 126
HotKeySet(Chr ( $char ),"writekeys")
$char = $char + 1
WEnd
while 1
sleep(10)
WEnd
Func writekeys()
HotKeySet(#HotKeyPressed)
send(#HotKeyPressed)
;do something
HotKeySet(#HotKeyPressed,"writekeys")
EndFunc
Related
Instead of the MsgBox i want the script to read a .txt file and write to the end of each line the result of a variable, in my case is $FileSize
Here is the code for autoit script
#include <MsgBoxConstants.au3>
#include <File.au3>
Test()
Func Test()
For $i = 1 to _FileCountLines(#TempDir & "\myfiles.txt")
$mread = FileReadLine(#TempDir & "\myfiles.txt", $i)
Local $FileSize = FileGetSize($mread)
MsgBox($MB_SYSTEMMODAL, "", ByteSuffix($FileSize)) ;this is just a test
Next
EndFunc ;==>Example
Func ByteSuffix($Bytes)
Local $Index = 0, $aArray = [' bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB']
While $Bytes > 1023
$Index += 1
$Bytes /= 1024
WEnd
Return Round($Bytes) & $aArray[$Index]
EndFunc
Here is the content of .txt file
C:\Users\G-PC\Documents\setup.exe
C:\Users\G-PC\Documents\config.ini
C:\Users\G-PC\Documents\image001.jpg
C:\Users\G-PC\Documents\image002.jpg
C:\Users\G-PC\Documents\image003.jpg
I want the following result
C:\Users\G-PC\Documents\setup.exe [SIZE FOR THIS]
C:\Users\G-PC\Documents\config.ini [SIZE FOR THIS]
C:\Users\G-PC\Documents\image001.jpg [SIZE FOR THIS]
C:\Users\G-PC\Documents\image002.jpg [SIZE FOR THIS]
C:\Users\G-PC\Documents\image003.jpg [SIZE FOR THIS]
There is a size limit for both string variables and arrays, so you have to process one line at a time when working with big files. This uses a temporary file for output instead of keeping all the information in memory. You can rename (overwriting the original file) the temporary file to the original file name at the end.
Func Test()
Local $InFile = FileOpen(#TempDir & "\myfiles.txt", $FO_READ)
Local $OutFile = FileOpen(#TempDir & "\myfiles.tmp", $FO_OVERWRITE)
While True
$File = FileReadLine($InFile)
If #error = -1 Then Return ; no more lines to process
FileWrite($OutFile, $File & " [" & ByteSuffix(FileGetSize($File)) & "]" & #CRLF)
WEnd
EndFunc ;==>Test
$sResult = Test()
ConsoleWrite('SIZE LIST' & #CRLF & $sResult)
Func Test()
Local $FileSize, $sReturn = ''
For $i = 1 to _FileCountLines(#TempDir & "\myfiles.txt")
$mread = FileReadLine(#TempDir & "\myfiles.txt", $i)
$FileSize = FileGetSize($mread)
; MsgBox($MB_SYSTEMMODAL, "", ByteSuffix($FileSize)) ;this is just a test
$sReturn &= $mread & " [" & ByteSuffix($FileSize) & "]" & #CRLF
Next
Return $sReturn
EndFunc ;==>Test
But a better way instead of reading the text file line by line is the using of _FileReadToArray. Than you can iterate through the array with text lines.
Using line number parameter for FileReadLine in a loop resets
the file pointer to the start and scans up to the line number which slows
down the loop as line count increases. Omit that parameter.
Use a file handle so you do not keep on opening and closing
the file with each line read in the loop.
#include <MsgBoxConstants.au3>
#include <File.au3>
$sResult = Test()
MsgBox(0, #ScriptName, $sResult)
Func Test()
Local $iFileSize, $hFile, $sFilePath, $sResult
; Open a file handle to read.
$hFile = FileOpen(#TempDir & "\myfiles.txt")
If $hFile = -1 Then
MsgBox(0x30, #ScriptName, 'Unable to open file to read.')
Exit 1
EndIf
While 1
; Read and let AutoIt handle line count.
$sFilePath = FileReadLine($hFile)
If #error Then ExitLoop
$iFileSize = FileGetSize($sFilePath)
If #error Then ContinueLoop
$sResult &= StringFormat('%s %s\r\n', $sFilePath, ByteSuffix($iFileSize))
WEnd
FileClose($hFile)
Return $sResult
EndFunc
Func ByteSuffix($Bytes)
Local $Index = 0
Local $aArray = [' bytes', ' KB', ' MB', ' GB', ' TB', ' PB', ' EB', ' ZB', ' YB']
While $Bytes > 1023
$Index += 1
$Bytes /= 1024
WEnd
Return Round($Bytes) & $aArray[$Index]
EndFunc
I have a script pushing "k" button in loop. I have added pause button on "q".
I also want "w" to pause the script. But I don want "w" to start my script. Is that possible?
Global $UnPaused
HotKeySet("q", "TogglePause")
HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{.}", "Terminate")
While 1
Sleep(100)
WEnd
Func TogglePause()
$UnPaused = NOT $UnPaused
While $UnPaused
Send("k")
WEnd
EndFunc
Func Terminate()
Exit 0
EndFunc
I suggest rearranging your code & introducing a Pause() function to make things easier:
Global $UnPaused=false;
HotKeySet("q", "Pause")
HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{.}", "Terminate")
While 1
if $UnPaused Then
Send("k");
Else
Sleep(100)
EndIf
WEnd
Func Pause()
$UnPaused = False
EndFunc
Func TogglePause()
$UnPaused = NOT $UnPaused
EndFunc
Func Terminate()
Exit 0
EndFunc
And if you don't want to capture a hotkey whilst paused, here's an example of that:
Global $UnPaused=false;
HotKeySet("q", "Pause")
HotKeySet("{PAUSE}", "TogglePause")
HotKeySet("{.}", "Terminate")
HotKeySet("w", "Pause")
While 1
if $UnPaused Then
HotKeySet("w", "Pause")
Send("k");
Else
HotKeySet("w")
Sleep(100)
EndIf
WEnd
Func Pause()
$UnPaused = False
EndFunc
Func TogglePause()
$UnPaused = NOT $UnPaused
EndFunc
Func Terminate()
Exit 0
EndFunc
My AutoIt script compiles but doesn't do what it's supposed to do. Code:
HotKeySet(+"{G}","gather")
While 1
sleep(100)
WEnd
Global $charRunTimeS = 2;
Global $collectKey = "{LWIN}";
Global $vehicleInvKey = "{T}";
Global $charRunTimeMS = $charRunTimeS * 1000
Global $posItemX = 820;
Global $posItem1Y = 300;
Global $posItem2Y = 340;
Global $posItem3Y = 365;
Global $posItem4Y = 397;
Global $posBtnStore = 678;
Global $posItemSelectedY = $posItem4Y
Func gather()
$counter = 0;
While $counter <= 2
Send("{s down}")
Sleep($charRunTimeMS)
Send("{s up}")
$counter1 = 0;
While $counter1 <= 4
Send($collectKey)
Sleep(100)
Send($collectKey)
Sleep(30000)
$counter1 = $counter1 + 1
WEnd
Send("{w down}")
Sleep($charRunTimeMS)
Send("{w up}")
Send($vehicleInvKey)
MouseClick("primary", $posItemX, $posItemSelectedY)
$counter2 = 0;
While $counter2 <= 30
MouseClick($posItemX, $posBtnStore)
$counter2 = $counter2 + 1
WEnd
Send("{ESC}")
$counter = $counter + 1
WEnd
EndFunc
Output from de-bug. First line is when compiling and running, the second line is when I stop the code:
"C:\Program Files (x86)\AutoIt3\SciTE..\autoit3.exe" /ErrorStdOut "C:\Users\RichusX\Desktop\AltisGatherScript.au3"
Process failed to respond; forcing abrupt termination...
Exit code: 1 Time: 14.39
I guess all you need to do is write the call like this:
HotKeySet("G", "gather")
You do not need the +, because of the capital G. If you want to then you have to put it into to "". Have a look at the send function.
So I am in need of replacing string text with autoit using stringreplace but I need to randomize the output.
An example of what I need is
Stringreplace($string, "and", {also|as well})
My ultimate goal is to randomly replace the text with the following options based on the word "and" with also or as well
I wrote this a long time ago.
It will convert this
My name is {John|Peter|Mark}! {Regards|Cheers|Get lost}!
to something like this
My name is John! Cheers!
It works with line breaks also.
Func SpintaxToTXT($TextWithSpintax)
Dim $MSGMSG
Dim $lines
$lines = StringSplit($TextWithSpintax, #LF)
For $z = 1 To $lines[0]
If $z > 1 Then $MSGMSG &= #LF
$d = StringSplit($lines[$z], "{}")
For $i = 1 To $d[0]
$MSGSplit = StringSplit($d[$i], "|")
If #error Then
$MSGMSG &= $MSGSplit[1]
ContinueLoop
EndIf
$MSGMSG &= $MSGSplit[Random(1, $MSGSplit[0], 1)]
Next
Next
Return $MSGMSG
EndFunc ;==>SpintaxToTXT
Try this:
Global $options_A = StringSplit('also,as well,bla,blubb,that,this', ',', 2)
For $i = 0 To 20
ConsoleWrite($options_A[Random(0, UBound($options_A) - 1, 1)] & #CRLF)
Next
Here's one I made earlier. Works exactly the same as StringReplace except instead of taking a replacement string, it takes a function that returns the replacement string. The using Xenobiologist's array method, you get the desired result.
Local $sTest = "The cat and the dog and the rat."
ConsoleWrite(_StringReplaceCallback($sTest, "and", _MyCallback) & #LF)
Func _MyCallback($s)
Local Static $aOptions = StringSplit("also|as well", "|")
Return $aOptions[Random(1, $aOptions[0], 1)]
EndFunc ;==>_MyCallback
Func _StringReplaceCallback($sString, $sFind, $funcReplace, $iOccurence = 0, $iCaseSense = 0)
Local $sRet = ""
Local $iDir = 1
Local $iPos = 1
If $iOccurence < 0 Then
$iDir = -1
$iPos = StringLen($sString)
EndIf
If $iOccurence = 0 Then $iOccurence = $iDir * StringLen($sString)
While 1
$i = StringInStr($sString, $sFind, $iCaseSense, $iDir, $iPos)
If $iDir > 0 Then
If Not $i Or Not $iOccurence Then
$sRet &= StringMid($sString, $iPos)
ExitLoop
EndIf
$sRet &= StringMid($sString, $iPos, $i - $iPos) & $funcReplace($sFind)
$iPos = $i + StringLen($sFind)
Else
If Not $i Or Not $iOccurence Then
$sRet = StringMid($sString, 1, $iPos) & $sRet
ExitLoop
EndIf
$sRet = $funcReplace($sFind) & StringMid($sString, $i + StringLen($sFind), $iPos - $i - StringLen($sFind) + 1) & $sRet
$iPos = $i - 1
EndIf
If $iOccurence <> 0 Then $iOccurence -= $iDir
WEnd
Return $sRet
EndFunc ;==>_StringReplaceCallback
It's probably worth noting that there is actually a simpler solution for this, provided the replacement strings don't ever include "and" (or else you'll have an infinite loop), that just replaces one instance at a time:
Local $sString = "The cat and the dog and the rat."
Local $aOptions = StringSplit("also|as well", "|")
Do
$sString = StringReplace($sString, "and", $aOptions[Random(1, $aOptions[0], 1)], 1)
Until Not #extended
ConsoleWrite($sString & #LF)
I'm creating a script that will open a program , login , and do specific tasks .
I created the login script with a variables adding and loopin through .
The problem is with the program , sometimes it just gives you an error on connection or a network problem .
What I need is IF the script gets the problem it'll reset it self and go through the account it got the error on , This is what I have so far and I just can't make it work
$t = 0
$n = "account"
$p = "password"
For $r = X To X
Run("program")
AutoITSetOption("MouseCoordMode", 0)
AutoITSetOption("WinTitleMatchMode", 3)
Do
Sleep(1000)
$t = $t + 1
Until WinActive("program") Or $t = 15
$t = 0
Sleep(1500)
Send("{TAB}")
Sleep(100)
Send("{TAB}")
Sleep(100)
Send("{Enter}")
Sleep(100)
Send($n & $r)
Sleep(200)
Send("{TAB}")
Sleep(200)
Send($p & $r)
Sleep(100)
Send("{Enter}")
Sleep(5500)
If $t > 14 Then
$r = $r - 1
Run(#ComSpec & " /c taskkill /F /im program.exe")
Do
Sleep(500)
$t = $t + 1
Until WinActive("Program - Update News") Or $t = 15
$t = 0
WinActivate("Program")
Sleep(2000)
MouseClick("Primary", 28, 12)
Sleep(1000)
MouseClick("Primary", 35, 125)
Sleep(1000)
MouseClick("Primary", 360, 175)
Sleep(2000)
Send("{ENTER}")
Sleep(2500)
Run(#ComSpec & " /c taskkill /F /im program.exe")
; EndIf
Next
Right now what it does is reruns the program without actually closing the error window
Hopefully this will give you a better idea of how to create a script and fix your problem. It is commented to give you an understanding of the steps taken.
#include <msgboxconstants.au3>
Local $t = 0, $n = "account", $p = "password" ; $n & $p are your own data
Local $r = ["X", "X", "X"], $e, $msg, $w ;$r is filled with your own data
AutoItSetOption("MouseCoordMode", 0)
AutoItSetOption("WinTitleMatchMode", 3)
HotKeySet("{ESC}", "Quit") ;If you want to exit the script, press the ESC key
Sender() ;call the function to run
While 1
If $e <> 0 Then ;if #error is set to a non-zero variable, wait 1 sec (1000 millisec) and run again
Sleep(1000)
Sender()
ElseIf $w = 0 Then ;if msgbox value is 0 AND retry OR ignore has been pressed, wait 1 second and run again
Sleep(1000)
$w += 1
Sender()
EndIf
WEnd
Func Sender() ;wrapped in function to make returning out of the function easier
For $r = "X" To UBound($r) ; for the first value in $r to the length of the array
Run("program")
$e = #error ;if Run sets #error then put #error and check the value with an if statement
If $e <> 0 Then
$msg = MsgBox(2, "ERROR", "error running program, exiting...")
If $msg = $IDABORT Then ;if we don't want to run the program again we abort
Quit()
ElseIf $msg = $IDRETRY Then ;if we want to retry then we hit retry
Return
ElseIf $msg = $IDIGNORE Then ;if we want to retry then we hit ignore as well
Return ;go out of the function because we have recieved an error and want to restart the function
EndIf
EndIf
SetError(0) ;sets #error to 0 so that we don't accidentally restart our program
Do
Sleep(1000)
$t += 1 ;add 1 to $t
Sleep(1500)
Send("{TAB}")
Sleep(100)
Send("{TAB}")
Sleep(100)
Send("{Enter}")
Sleep(100)
Send($n & $r)
Sleep(200)
Send("{TAB}")
Sleep(200)
Send($p & $r)
Sleep(100)
Send("{Enter}")
Sleep(5500)
If $t > 14 Then
$r -= 1 ;minus 1 from $r
Run(#ComSpec & " /c taskkill /F /im program.exe")
$e = #error
If $e <> 0 Then
$msg = MsgBox(2, "ERROR", "error running " & #ComSpec & " /c taskkill /F /im program.exe, Abort to Quit; Retry & Ignore to RETRY.")
If $msg = $IDABORT Then
Quit()
ElseIf $msg = $IDRETRY Then
Return
ElseIf $msg = $IDIGNORE Then
Return
EndIf
EndIf
EndIf
SetError(0)
Until WinActive("program") Or $t = 15
$t = 0 ;set $t to 0
Do
Sleep(500)
$t += 1
$w = WinActivate("Program")
If $w = 0 Then
$msg = MsgBox(2, "ERROR", "error activating program, Abort to Quit; Retry & Ignore to RETRY.")
If $msg = $IDABORT Then
Quit()
ElseIf $msg = $IDRETRY Then
Return
ElseIf $msg = $IDIGNORE Then
Return
EndIf
EndIf
$w += 1
Sleep(2000)
MouseClick("Primary", 28, 12)
Sleep(1000)
MouseClick("Primary", 35, 125)
Sleep(1000)
MouseClick("Primary", 360, 175)
Sleep(2000)
Send("{ENTER}")
Sleep(2500)
Run(#ComSpec & " /c taskkill /F /im program.exe")
$e = #error
If $e <> 0 Then
$msg = MsgBox(2, "ERROR", "error running " & #ComSpec & " /c taskkill /F /im program.exe, Abort to Quit; Retry & Ignore to RETRY.")
If $msg = $IDABORT Then
Quit()
ElseIf $msg = $IDRETRY Then
Return
ElseIf $msg = $IDIGNORE Then
Return
EndIf
EndIf
SetError(0)
Until WinActive("Program - Update News") Or $t = 15
Next
EndFunc ;==>Sender
Func Quit() ;will be called when we want to completely stop the script
Exit
EndFunc ;==>Quit