Maintaing value of a string after restarting the script

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
blehmeco
Posts: 3
Joined: 17 Nov 2017, 13:17

Maintaing value of a string after restarting the script

17 Nov 2017, 20:13

I have a script that opens a GUI with some buttons, when pressed they create an array of strings, shown on a list view in real time.
After I close the GUI the script keeps running and making changes from time to time to that array of strings.
I want to be able to open the script again (double clicking it, as I'm compiling to .exe) and have it show in the GUI's list view the current contents of the array.
I know I can simply use a .txt file and write the string to that file and read from it on restarting the script, but I want to reduce this to one .exe file.

Ideas for a clean getaway?
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Maintaing value of a string after restarting the script

17 Nov 2017, 20:23

The answer would be to never close the script. You can do this by checking the exit reason via onExit.

Code: Select all

#singleInstance force
onExit,checkExit
..

checkExit:
if(a_exitReason="Single"){
    ; do something
}else
    exitApp
return
The above (untested) code will allow re-launching the exe to trigger whatever you put in those brackets, but any other method will successfully close it. See the linked documentation for more exit reason codes.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
blehmeco
Posts: 3
Joined: 17 Nov 2017, 13:17

Re: Maintaing value of a string after restarting the script

17 Nov 2017, 21:00

It never closes, only the GUI disappears!
As I mentioned above, the script keeps running and making changes to the string after the GUI closes. Only when re-opening the script (with it already running), to take a peek at the state of the string, it gets lost.
I believe by using "#singleinstance, force", it just restarts a new script replacing the previous instance of it and so the string stored in the variable resets to nothing...
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Maintaing value of a string after restarting the script

17 Nov 2017, 21:31

That would be incorrect. By using #singleInstance force, it ensures that it will attempt to close the currently running script. Then, the onExit subroutine will catch that request and essentially ignore it. Where I made the ; do something comment, put in gui,show, including whatever GUI name you may have for it. This absolutely does work, I just tested it.

However, in testing, I've found that it doesn't suppress the prompt that it "Could not close previous instance of this script." Not sure if there's a proper way to do that. Your best option would be to allow the GUI to show otherwise, either by adding a hotkey/hotstring or using the double-click of the tray icon. Otherwise, you'd have to interact with the prompt or process of the prompt. The process would be the same exact name and file path, but with a different PID, so you could check against that.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build
blehmeco
Posts: 3
Joined: 17 Nov 2017, 13:17

Re: Maintaing value of a string after restarting the script

17 Nov 2017, 21:50

Introduced the changes but it's not opening... sorry for the (probable) rookiness here!
Can you take a look?

Code: Select all

#NoTrayIcon
#SingleInstance, force
#Persistent
OnExit, CheckExit

CheckExit:
If(A_ExitReason="Single"){
 GuiControl,, MyArray, %MyArray%
 Gui, Show, h500 w200
}Else
    ExitApp
Return

SleepTill(Time) {
 ST_Hour:=SubStr(Time, 1 ,2)
 ST_Min:=SubStr(Time, 3 ,2)
 ST_Sec:=(SubStr(Time, 5 ,2)<>"" ? SubStr(Time, 5 ,2) : "00")
 STime:=(((ST_Hour-A_Hour)*60+(ST_Min-A_Min))*60+(ST_Sec-A_Sec))*1000 
 STime:=STime<0 ? STime+86400000 : STime
 Sleep %STime%
 Return % A_Hour ":" A_Min
}

Gui, Add, Button, gInputSub, Input
Gui, Add, Button, gOutput14Sub, Output14
Gui, Add, Text,, 
Gui, Add, Button, gGenerateSub, Generate
Gui, Add, Edit, R10 vMyArray
GuiControl,, MyArray, %MyArray%
Gui, Show, h300 w200
Return MyArray

InputSub:
Random, ChosenTime, 742, 759
ChosenTime := 0 . ChosenTime
GoSub, UpdateBox
Return

Output14Sub:
Random, ChosenTime, 1400, 1409
GoSub, UpdateBox
Return

GenerateSub:
MsgBox, Array: `r`n%MyArray%
GoSub, ReadMyArrayAndDoStuff
Return MyArray

UpdateBox:
MyArray := MyArray . ChosenTime . "`n"
GuiControl,, MyArray, %MyArray%
Return

ReadMyArrayAndDoStuff:
Loop, Parse, MyArray, `n
 {
  MsgBox, Line %A_Index% is %A_LoopField%
  If StrLen(A_LoopField) < 3 {
   MsgBox, This is the end 
   ExitApp
  }
  IfNotInString, A_LoopField, O
  {
   StringReplace, TimeForThePike, A_LoopField, `n`r, , All
   SleepTill(TimeForThePike)
   MyArray := MyArray . 1
  }
 }
Return
User avatar
Masonjar13
Posts: 1555
Joined: 20 Jul 2014, 10:16
Location: Не Россия
Contact:

Re: Maintaing value of a string after restarting the script

17 Nov 2017, 23:08

Certainly! Looks like you just need to rearrange your code a bit.

Code: Select all

#NoTrayIcon
#SingleInstance, force
#Persistent
OnExit, CheckExit

Gui, Add, Button, gInputSub, Input
Gui, Add, Button, gOutput14Sub, Output14
Gui, Add, Text,, 
Gui, Add, Button, gGenerateSub, Generate
Gui, Add, Edit, R10 vMyArray
GuiControl,, MyArray, %MyArray%
Gui, Show, h300 w200
Return MyArray

InputSub:
Random, ChosenTime, 742, 759
ChosenTime := 0 . ChosenTime
GoSub, UpdateBox
Return

Output14Sub:
Random, ChosenTime, 1400, 1409
GoSub, UpdateBox
Return

GenerateSub:
MsgBox, Array: `r`n%MyArray%
GoSub, ReadMyArrayAndDoStuff
Return MyArray

UpdateBox:
MyArray := MyArray . ChosenTime . "`n"
GuiControl,, MyArray, %MyArray%
Return

ReadMyArrayAndDoStuff:
Loop, Parse, MyArray, `n
 {
  MsgBox, Line %A_Index% is %A_LoopField%
  If StrLen(A_LoopField) < 3 {
   MsgBox, This is the end 
   ExitApp
  }
  IfNotInString, A_LoopField, O
  {
   StringReplace, TimeForThePike, A_LoopField, `n`r, , All
   SleepTill(TimeForThePike)
   MyArray := MyArray . 1
  }
 }
Return

CheckExit:
If(A_ExitReason="Single"){
 GuiControl,, MyArray, %MyArray%
 Gui, Show, h500 w200
}Else
    ExitApp
Return

SleepTill(Time) {
 ST_Hour:=SubStr(Time, 1 ,2)
 ST_Min:=SubStr(Time, 3 ,2)
 ST_Sec:=(SubStr(Time, 5 ,2)<>"" ? SubStr(Time, 5 ,2) : "00")
 STime:=(((ST_Hour-A_Hour)*60+(ST_Min-A_Min))*60+(ST_Sec-A_Sec))*1000 
 STime:=STime<0 ? STime+86400000 : STime
 Sleep %STime%
 Return % A_Hour ":" A_Min
}
AutoHotkey is procedural in that it reads top to bottom. Labels to not stop auto-execution, so it was running CheckExit before any other code. And while functions don't interrupt the flow, it's typically easier to read when they're either in a library or at the bottom of the script. Unlike some other languages, such as C++, functions do not need to be declared prior to using them. That's really just preference, though.
OS: Windows 10 Pro | Editor: Notepad++
My Personal Function Library | Old Build - New Build

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: filipemb, mikeyww and 187 guests