setworkingdir in one thread breaks includes in other thread

Ask for help, how to use AHK_H, etc.
User avatar
bichlepa
Posts: 183
Joined: 15 Aug 2014, 06:44
Location: Germany
Contact:

setworkingdir in one thread breaks includes in other thread

Post by bichlepa » 28 Sep 2020, 13:13

If a thread starts which has includes, and another thread changes the working directory at same time, the includes may fail, because AHK tries to include the file from the new working directory. It happens even when the include path is set to script directory.
Start the attached code.

This script needs to be started multiple times in a thread to reproduce the error. In the attached zip-file, the full code and a script which starts multiple threads, is included.

Code: Select all

  
  #include %a_scriptdir%
  #include includes/include 1.ahk
  #include includes/include 2.ahk
  ; code cropped
  #include includes/include 1000.ahk
SetWorkingDir, %a_temp%
SetWorkingDir, %a_temp%
SetWorkingDir, %a_temp%
SetWorkingDir, %a_temp%
SetWorkingDir, %a_temp%
missedIncludes := ""
loop 1000
{
if not included%a_index%
  {
    missedIncludes .= "included0.ahk, "
  }
}
msgbox % missedIncludes
In this test code every time, when a file can't be included, an error message is shown.

I stumbled on that issue, while I did some Debugging of AutoHotFlow.

During development of AutoHotFlow I experience that sometimes some random files are not included and if there is an error message, it tells that a function implementation is missing. In some modules, the functions are called via dynamic calls and there an error occures on runtime when the script tries to call a function from a missing module.
However, deleting the "setworkingdir" calls did not solve the problem.
Attachments
test includes.zip
(175.9 KiB) Downloaded 62 times
Scripting is too complicated? Try AutoHotFlow, the graphical automation tool! Written in AutoHotkey.

HotKeyIt
Posts: 2364
Joined: 29 Sep 2013, 18:35
Contact:

Re: setworkingdir in one thread breaks includes in other thread

Post by HotKeyIt » 28 Sep 2020, 20:12

There is only one working directory per process, and you should avoid changing it. See https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-setcurrentdirectory
Multithreaded applications and shared library code should not use the SetCurrentDirectory function and should avoid using relative path names. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, therefore multithreaded applications cannot reliably use this value without possible data corruption from other threads that may also be reading or setting this value. This limitation also applies to the GetCurrentDirectory and GetFullPathName functions. The exception being when the application is guaranteed to be running in a single thread, for example parsing file names from the command line argument string in the main thread prior to creating any additional threads. Using relative path names in multithreaded applications or shared library code can yield unpredictable results and is not supported.

User avatar
bichlepa
Posts: 183
Joined: 15 Aug 2014, 06:44
Location: Germany
Contact:

Re: setworkingdir in one thread breaks includes in other thread

Post by bichlepa » 29 Sep 2020, 09:46

Thanks for the explanation. IMHO this explanation should be somewhere in the documentation of AHK_H. Maybe here: https://documentation.help/AHK_H-2.0/SetWorkingDir.htm
Scripting is too complicated? Try AutoHotFlow, the graphical automation tool! Written in AutoHotkey.

Post Reply

Return to “Ask for Help”