Calling commands from a variable Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Calling commands from a variable

Post by zabbn » 01 Dec 2022, 12:26

Hi, I would like to do the following:

Code: Select all

doThis=
(
Run, notepad.exe
WinWaitActive, ahk_exe notepad.exe
Send,^v
Sleep, 1000
send,^a
Sleep, 500
send,^x
Sleep, 200
WinKill,A
)

^!v::
callCommandsFromVariableFunction(%doThis%)
return

callCommandsFromVariableFunction(commands)
Loop,Parse,commands,`n
{
   ;the following lines should execute each line of the variable as a command
   StrSplit(A_Loopfield,",")
   'execute', % A_Loopfield[1]
   'with parameters', %A_Loopfield[2]
}
Is something like this possible with AHK?
I read this viewtopic.php?t=24480, where Exaskryz said it is not possible. I was wondering and hoping that it may not be unachievable.

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 01 Dec 2022, 12:30

Code: Select all

doThis=
(
Run, notepad.exe
WinWaitActive, ahk_exe notepad.exe
Send,^v
Sleep, 1000
send,^a
Sleep, 500
send,^x
Sleep, 200
WinKill,A
)

ExecScript(doThis)

ExecScript(script, exePath := "") {
   (!exePath && exePath := A_AhkPath)
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(exePath . " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.ProcessID
}

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 01 Dec 2022, 12:38

Wow, thank you for your blazingly fast answer.
teadrinker wrote:
01 Dec 2022, 12:30

Code: Select all

ExecScript(script, exePath := "") {
   (!exePath && exePath := A_AhkPath)
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(exePath . " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.ProcessID
}
Could you elaborate a little on this? I have never worked with ComObjects and I honestly don't even understand the first line of the function (the !exePath && part).

In case it is too much work to explain, two other questions:
1. Can I use any combination of command concatenation in my variable?
2. I don't need to loop and split the string, call commands and parameters separately?

Thank you!

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 01 Dec 2022, 13:05

zabbn wrote: I honestly don't even understand the first line of the function (the !exePath && part).
(!exePath && exePath := A_AhkPath) is the same as

Code: Select all

if !exePath {
   exePath := A_AhkPath
}
zabbn wrote: 1. Can I use any combination of command concatenation in my variable?
Yep, keeping the correct AHK syntax.
zabbn wrote: 2. I don't need to loop and split the string, call commands and parameters separately?
Can you clarify what you mean?

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 01 Dec 2022, 13:26

teadrinker wrote: Can you clarify what you mean?
I think I understand already, I was talking about the StrSplit(A_Loopfield) that I mentioned in my first post. I don't need it as I understand.

I have tested it with simple variables and it works thus far. I read a little in https://www.autohotkey.com/docs/commands/Run.htm and what the wscript.Shell is. I still don't understand it fully, but it has solved my question, even though I may not be able to troubleshoot it when running into problems.

Thank you very much for your help teadrinker !

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 01 Dec 2022, 13:34

Feel free to ask questions here! :)

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 02 Dec 2022, 04:26

teadrinker wrote:
01 Dec 2022, 13:34
Feel free to ask questions here! :)
Will do ;) :
As far as I understand, the exec uses the cmd.exe of windows. Thus, it somewhat opens another thread.

Is there a way to wait for the execution of the WScript.Shell to have finished before my AHK script continues? Currently, while the function is running the 'StdIn', my script continues and eventually exits before the commands have even been executed (even though they still execute after the script is closed, of course).
I would like to keep the script on hold until at least the return exec.ProcessID is reached by the cmd.exe.


btw: what does

Code: Select all

exec.ProcessID
do?

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 02 Dec 2022, 05:21

zabbn wrote: btw: what does

Code: Select all

exec.ProcessID
do?
It returns a Process identifier.
zabbn wrote: Is there a way to wait for the execution of the WScript.Shell to have finished before my AHK script continues?
Yes, like this:

Code: Select all

ExecScript("MsgBox Child script")
MsgBox Main script

ExecScript(script, exePath := "") {
   (!exePath && exePath := A_AhkPath)
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(exePath . " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.StdOut.ReadAll()
}
zabbn wrote: As far as I understand, the exec uses the cmd.exe of windows.
No, it doesn't.

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 02 Dec 2022, 07:46

Thank you for the code! It works with exec.StdOut.ReadAll().
teadrinker wrote:
02 Dec 2022, 05:21
zabbn wrote: As far as I understand, the exec uses the cmd.exe of windows.
No, it doesn't.
Can you or someone point me to some nooby friendly resource where I could learn about how it works?

One more thing, it's off-topic but it's minor:
I'd like to differentiate between 1-0 and Numpad1-0 with Input:

Code: Select all

Input,UInput,L1,%matchlist%,endkeylist
If UInput="1"
	do1
If UInput="Numpad1"
	do2
Is that possible? What I read, as the VKs are the same, it can not be distinguished with Input? Any idea?

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 02 Dec 2022, 13:05

zabbn wrote: Can you or someone point me to some nooby friendly resource where I could learn about how it works?
I've never been interested in this, so I don't know many resources.
Exec Method (Windows Script Host)
zabbn wrote: I'd like to differentiate between 1-0 and Numpad1-0 with Input:
Please, create a separate topic.

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 02 Dec 2022, 15:53

Thanks for the link!

Yes you're right, numpad is a different topic.

On-topic though:
How can I call subroutines / labels with this Exec method?

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 02 Dec 2022, 16:15

zabbn wrote: How can I call subroutines / labels with this Exec method?

Code: Select all

script =
(
   GoSub, MyLabel
   Return
   
   MyLabel:
      MsgBox, MyLabel in child script
      Return
)

ExecScript(script)
MsgBox Main script

ExecScript(script, exePath := "") {
   (!exePath && exePath := A_AhkPath)
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(exePath . " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.StdOut.ReadAll()
}

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 02 Dec 2022, 16:24

teadrinker wrote:
02 Dec 2022, 16:15

Code: Select all

script =
(
   GoSub, MyLabel
   Return
   
   MyLabel:
      MsgBox, MyLabel in child script
      Return
)
Okay, many thanks. But there is no way to have them outside the

Code: Select all

 script=
part and call them from inside 'script' ?

Right now I'm working on StrReplace - ing them with the keyword gosub, as the needle and a variable with the name of the subroutine. That is some work, but it's a workaround I guess.

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable

Post by teadrinker » 02 Dec 2022, 16:31

zabbn wrote: But there is no way to have them outside
Nope, the code is launched as a separate process with its own separated memory.

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 02 Dec 2022, 16:51

teadrinker wrote:
02 Dec 2022, 16:31
zabbn wrote: But there is no way to have them outside
Nope, the code is launched as a separate process with its own separated memory.
Alright thank you very much for your help! Learned a lot.

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 06 Dec 2022, 14:32

sorry I have to stir this up again, but I have not been able to find a solution for this anywhere.
I would like to be able to close the child script that I executed with exec.StdIn.Write(script). However, I can not change the name here: shell.Exec(exePath . " *").
Currently, the resulting ahk script is named " *" which I can not easily address with a WinTitle Match (for example to kill the process).

How can I rename the child script?

teadrinker
Posts: 4309
Joined: 29 Mar 2015, 09:41
Contact:

Re: Calling commands from a variable  Topic is solved

Post by teadrinker » 06 Dec 2022, 16:24

You don't need to rename the script, you can use its PID like this:

Code: Select all

PID := ExecScript("MsgBox, Child script")
Sleep, 1000
DetectHiddenWindows, On
WinMenuSelectItem, ahk_class AutoHotkey ahk_pid %PID%,, 1&, 8& ; select menu item File —> Exit (Terminate script)

ExecScript(script, exePath := "") {
   (!exePath && exePath := A_AhkPath)
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(exePath . " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.ProcessID
}

User avatar
zabbn
Posts: 47
Joined: 30 Apr 2020, 03:34
Location: Germany

Re: Calling commands from a variable

Post by zabbn » 06 Dec 2022, 16:32

teadrinker wrote:
06 Dec 2022, 16:24
You don't need to rename the script, you can use its PID like this:

Code: Select all

PID := ExecScript("MsgBox, Child script")
Sleep, 1000
DetectHiddenWindows, On
WinMenuSelectItem, ahk_class AutoHotkey ahk_pid %PID%,, 1&, 8& ; select menu item File —> Exit (Terminate script)

ExecScript(script, exePath := "") {
   (!exePath && exePath := A_AhkPath)
   shell := ComObjCreate("WScript.Shell")
   exec := shell.Exec(exePath . " *")
   exec.StdIn.Write(script)
   exec.StdIn.Close()
   return exec.ProcessID
}
Oh man, thank you! I could have gotten there, you even mentioned exec.ProcessID in your initial response and I asked about it :silent:

Post Reply

Return to “Ask for Help (v1)”