[BUG] Compiled script: Run/RunWait launch the wrong executable Topic is solved

Report problems with documented functionality
User avatar
Guillaume
Posts: 20
Joined: 24 Nov 2017, 14:06

[BUG] Compiled script: Run/RunWait launch the wrong executable

16 Oct 2023, 09:22

neogna2 wrote:In compiled scripts using Run/RunWait with only a filename as target (no explicit target path) makes the script search A_ScriptDir before A_WorkingDir, a behaviour that differs from Run documentation:
If Target is a local file and no path was specified with it, A_WorkingDir will be searched first.
viewtopic.php?p=543643#p543643

For example, compile the following to ahkdir.exe:
MsgBox, %A_ScriptDir%

Create ahktest.ahk with the following and compile it to ahktest.exe:
Run ahkdir.exe
SetWorkingDir %A_Temp%
Run ahkdir.exe


Copy ahkdir.exe both to %A_Temp% and next to ahkdir.exe.

Result:
- The uncompiled ahktest.ahk does what's expected:it launches %A_ScriptDir%\ahkdir.exe, then %A_Temp%\ahkdir.exe.
- However, ahktest.exe launches %A_ScriptDir%\ahkdir.exe twice.

Windows 10 x64
Running AHK/AHK2EXE v1.1.37.01 (32-bit ANSI/Unicode or 64-bit doesn't matter)
Last edited by Guillaume on 18 Oct 2023, 06:38, edited 3 times in total.
TAC109
Posts: 1129
Joined: 02 Oct 2013, 19:41
Location: New Zealand

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

17 Oct 2023, 16:44

Seems to be an AutoHotkey bug. Also happens with v2.0.10. @boiler Could you please move this thread to the 'bug reports' section of the forum. Thanks.
Last edited by TAC109 on 19 Oct 2023, 16:29, edited 1 time in total.
My scripts:-
XRef - Produces Cross Reference lists for scripts
ReClip - A Text Reformatting and Clip Management utility
ScriptGuard - Protects Compiled Scripts from Decompilation
I also maintain Ahk2Exe
User avatar
boiler
Posts: 17384
Joined: 21 Dec 2014, 02:44

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

17 Oct 2023, 17:13

TAC109 wrote: @boiler Could you please move this thread to the 'bug reports' section of the forum. Thanks.
:thumbup:
neogna2
Posts: 600
Joined: 15 Sep 2016, 15:44

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

18 Oct 2023, 04:12

After tests in v2:
This happens not only for A_Temp but with any folder.
When running the .exe A_WorkingDir is correctly set, as shown if we add line MsgBox A_WorkingDir after the SetWorkingDir line.
So the general bug description could be: in compiled scripts using Run with only a filename as target (no explicit target path) makes the script search A_ScriptDir before A_WorkingDir, a behaviour that differs from Run documentation
If Target is a local file and no path was specified with it, A_WorkingDir will be searched first.
User avatar
Guillaume
Posts: 20
Joined: 24 Nov 2017, 14:06

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

18 Oct 2023, 06:38

neogna2 wrote:
18 Oct 2023, 04:12
After tests in v2:
This happens not only for A_Temp but with any folder.
When running the .exe A_WorkingDir is correctly set, as shown if we add line MsgBox A_WorkingDir after the SetWorkingDir line.
So the general bug description could be: in compiled scripts using Run with only a filename as target (no explicit target path) makes the script search A_ScriptDir before A_WorkingDir, a behaviour that differs from Run documentation
If Target is a local file and no path was specified with it, A_WorkingDir will be searched first.
Correct. I wasn't clear on that. Using A_Temp in the code is just an example. I've added your bug description to the first post.
lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

19 Oct 2023, 22:33

This is an error in the documentation.

AutoHotkey itself does no searching for files. The system functions CreateProcess and ShellExecuteEx are entirely responsible for defining the search order.
If the file name does not contain a directory path, the system searches for the executable file in the following sequence:
  1. The directory from which the application loaded.
  2. The current directory for the parent process.
    ...
Source: CreateProcessW function (processthreadsapi.h) - Win32 apps | Microsoft Learn
I have not found any clear documentation for how ShellExecuteEx locates the target file.

Run/RunWait attempts CreateProcess first, unless you specify a verb such as properties or *compile. If CreateProcess fails and RunAs isn't in effect, Run/RunWait then attempts ShellExecuteEx. CreateProcess only supports executable files, not scripts, documents or the like. ShellExecuteEx has different behaviour; e.g. it reads the "App Paths" registry key and does not search the application directory.

For instance, Run 'AutoHotkey64.exe "' A_ScriptFullPath '"' will generally work if AutoHotkey64.exe exists in the same directory as the current AutoHotkey interpreter, but Run 'properties AutoHotkey64.exe' or Run 'AutoHotkey.chm' will not work unless the working directory is set appropriately.

Windows 10+ also has "app execution aliases", but I think those are implemented via the WindowsApps folder in PATH.

N.B. The shortest way to specify a file in the working directory is .\filename.
User avatar
Guillaume
Posts: 20
Joined: 24 Nov 2017, 14:06

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

19 Oct 2023, 22:54

@lexikos Does that explain what is happening here? I'm confused.

I'm less confused about why only the compiled version exhibited this behavior, though: it's because the interpreter's executable is elsewhere. So if I copy autohotkeyu64.exe as ahktest.exe and run the script ahktest.ahk via that exe, it exhibits the same behavior as the compiled version.

That makes total sense, but the issue that Run/RunWait, or CreateProcess, don't use the WorkingDir should be something that AutoHotkey can handle better by always passing on the lpCurrentDirectory, right?
lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

20 Oct 2023, 01:43

Does that explain what is happening here?
Yes.
... the issue that Run/RunWait, or CreateProcess, don't use the WorkingDir should be something that AutoHotkey can handle better ...
I do not believe that changing the behaviour to match the current documentation would be handling it better.

Run/RunWait has likely behaved this way since its inception. It is safe to assume that there are scripts which rely on the current search order.

"A_WorkingDir will be searched first" isn't just incorrect because the application directory might take predence; it is also incorrect because A_WorkingDir won't be searched at all if WorkingDir specifies some other directory.

When Run/RunWait uses CreateProcess, Target is interpreted entirely by CreateProcess, not by Run/RunWait. In order to change the behaviour so that WorkingDir takes precedence, Run/RunWait would need to interpret Target to determine whether the file exists in WorkingDir. Although it already does something like that for ShellExecuteEx by necessity (since it accepts the target file and parameters separately), there is a risk that any parsing done by Run/RunWait will differ from CreateProcess in some subtle way, causing a change in behaviour beyond what is intended.

... by always passing on the lpCurrentDirectory, right?
If you mean "by always passing WorkingDir to the lpCurrentDirectory parameter of CreateProcess", it already does that. Even if CreateProcess executes a file in the application directory instead of the working directory, the working directory of the new process will be initially set to WorkingDir.
neogna2
Posts: 600
Joined: 15 Sep 2016, 15:44

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

20 Oct 2023, 09:30

Thank you Lexikos!
To get this stuff to stick in my brain I tried summarizing it, based on tests in v2. Let me know if anything is faulty.

What happens when Run has a target parameter that is a filename without any path specified?
We can explain using the case of two AutoHotkey scripts, where one uses Run to run the other.
Let's use the name "target" for the script that we call and the name "caller" for the calling script (that contains the Run line).
What happens depends on two things: if target is compiled and if caller is compiled.
What happens depends on two things: whether target is compiled and and where the calling process is located.
We can imagine four simple cases (set other possible cases aside):
- caller.ahk doing Run "target.ahk"
- caller.ahk doing Run "target.exe"
- caller.exe doing Run "target.ahk"
- caller.exe doing Run "target.exe"

Caller uses CreateProcess if target is .exe (compiled script or other executable file)
Caller uses ShellExecuteEx if target is .ahk (non-executable file)

CreateProcess
Where the calling process is located matters for the order CreateProcess searches for the target file.
If caller is uncompiled (caller.ahk) then the process actually running the script is A_AhkPath. For example C:\Program Files\AutoHotkey\AutoHotkey.exe .
If caller is compiled (caller.exe) then it is itself the process running the script, from A_ScriptDir. For example C:\MyScripts\caller.exe .
The CreateProcess documentation specifies the search order "[if] the file name does not contain a directory path":
1. The directory from which the application loaded.
2. The current directory for the parent process. ...
Which means
- in caller.exe 1 is A_ScriptDir
- in caller.ahk 1 is the folder that A_AhkPath is in.
- in an .exe or .ahk caller 2 is WorkingDir (Run's 2nd parameter) if set and otherwise caller's A_WorkingDir which defaults to A_ScriptDir

ShellExecuteEx
The documentation for the related SHELLEXECUTEINFOA structure says
lpFile ... name of the file ... If the path is not included ... current directory is assumed. ...
lpDirectory ... Optional ... name of the working directory. If ... NULL ... current directory is used as the working directory.
Which means
- in an .exe or .ahk caller the target is searched for in WorkingDir (Run's 2nd parameter) if set or otherwise in caller's A_WorkingDir which defaults to A_ScriptDir. There is no other search step.


We can now explain what happens in Guillaume's first post
When the caller is .exe Run (CreateProcess) first searches in A_ScriptDir and finds ahkdir.exe there and runs it. Both times.
When the caller is .ahk Run (CreateProcess) first searches in the folder that contains A_AhkPath (for example C:\Program Files\AutoHotkey ) and doesn't find ahkdir.exe there so falls back to searching in A_WorkingDir, which is A_ScriptDir in the first Run and A_Temp in the second Run.

Some relevant AutoHotkey source locations
https://github.com/AutoHotkey/AutoHotkey/blob/v2.0/source/lib/process.cpp#L172
https://github.com/AutoHotkey/AutoHotkey/blob/v2.0/source/script.cpp#L12258
https://github.com/AutoHotkey/AutoHotkey/blob/v2.0/source/script.cpp#L12420
https://github.com/AutoHotkey/AutoHotkey/blob/v2.0/source/script.cpp#L12538

(edited based on lexikos comment below)
Last edited by neogna2 on 23 Oct 2023, 16:29, edited 4 times in total.
User avatar
Guillaume
Posts: 20
Joined: 24 Nov 2017, 14:06

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

20 Oct 2023, 10:07

Thanks @neogna2, that seems like a pretty complete description of what occurs.

I've also tested @lexikos's suggestion to use .\ahkdir.exe instead, and that indeed solves the issue. I think it would be a nice addition to the documentation after explaining the distinction in behavior.
lexikos
Posts: 9690
Joined: 30 Sep 2013, 04:07
Contact:

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable  Topic is solved

23 Oct 2023, 02:39

neogna2 wrote:
20 Oct 2023, 09:30
What happens depends on two things: if target is compiled and if caller is compiled.
That's assuming that the script itself is the target file. I don't see Run ahktest.ahk in the previous posts. Run %A_AhkPath% /script ahktest.ahk would run an uncompiled script, most likely with CreateProcess. It can even work if the caller is compiled (based on an .exe file and not a .bin file).

What happens depends on whether the target is an .exe file, and where the calling process/exe is.

I update the v1 documentation shortly after my previous post.
neogna2
Posts: 600
Joined: 15 Sep 2016, 15:44

Re: [BUG] Compiled script: Run/RunWait launch the wrong executable

23 Oct 2023, 16:27

Helpful comment, thanks, I've updated my text above based on it.

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 15 guests