Page 1 of 1

Executable folder location

Posted: Fri Feb 17, 2023 2:10 pm
by Catdaddy
This may be more of a Windows question but it involves PureBasic so here goes:

I wrote a shell replacement in PureBasic for a Point of Sale register which runs on Windows 10. When the register boots up, instead of running Explorer.exe, which is the normal Windows shell, I made a registry entry that points to my shell program to run instead:

HKCU\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Shell\POSShell.exe

POSShell.exe resides in C:\Shell which is included in the environment variable %PATH% so it can be launched from anywhere.

This works fine except my shell program reads an .INI file located in the same directory as the shell executable. When I boot the machine and my shell program starts up, it is unable to see or find the .INI file.

After some experimentation, I inserted this into my code:

Debug (GetCurrentDirectory())

The debug message returns: C:\Windows\System32

Should it not return: C:\Shell ?

If I run POSShell.exe after letting Windows boot regularly to Explorer then it finds and reads the .INI file just fine and the debug message returns C:\Shell.

Now, to make matters worse, I have a shell that I wrote previously in AutoIt that is setup identically as above and when launched with the registry pointing to it, executes perfectly and reads the .INI file just fine.

If I hard code the path of the .INI file in my program it works just fine but I don't want to do that.

As I say, this may not be a direct PureBasic problem but I am stumped and would welcome any input you could give. I can post my code if that will help. Thank you.

Re: Executable folder location

Posted: Fri Feb 17, 2023 2:25 pm
by Axolotl
I never rely on the current folder (directory setting)

I always use below code (part of a big include file) for my portable apps.

Code: Select all

; ---== Development Constants ==---------------------------------------------------------------------------------------
#CurrentCompilerVersion        = 600                   ; <==> set to the compiler you use 
#DefaultSourceName$            = "PB_EditorOutput.pb"  ; <==> unnamed file is called 'PB_EditorOutput.pb' 

; -----------------------------------------------------------------------------

Procedure.s ExecutablePath()    ; -- at runtime only, "" at development time 
  Static s_path$ = "" 

  If s_path$ = ""  ; first call .. examine the path 
    CompilerIf #PB_Compiler_Debugger         ; .. at development time 
      CompilerIf #DEV_MainSourceName$ = #DefaultSourceName$ 
        Debug "HINT: " + #PB_Compiler_Procedure + "() with unsaved main file " 
        ; return empty string 
  	  CompilerElse 
  	    s_path$ = #DEV_MainSourcePath$ 
  	  CompilerEndIf 
    CompilerElse                             ; .. at runtime 
      s_path$ = GetPathPart(ProgramFilename()) 
    CompilerEndIf 
  EndIf                                       ;:DebugProcName + "-> return '" + s_path$ + "'" 
  ProcedureReturn s_path$ 
EndProcedure 


in my main file i define the following constant:

Code: Select all

;; ---== internally used in INCLUDE files according to the specific main source file ==---------------------------------
#DEV_MainSourcePath$   = #PB_Compiler_FilePath ; this kept the file directory (path) of the main source 
#DEV_MainSourceName$   = #PB_Compiler_Filename ;  -"-          file name  -"- 
P.S. Windows is from my point of view already for a long time very special with directories...
If you do not want to experience any surprises you should probably put programs and data in the designated directories...

Happy coding and stay healthy.

Re: Executable folder location

Posted: Fri Feb 17, 2023 2:54 pm
by nsstudios
I've fallen for this before as well.
GetCurrentDirectory() gives you the current working directory, which can be set by a third-party, e.g., shortcut, another program, etc.
ProgramFilename() gives you the absolute path to your executable, so if you want to make absolutely sure your current directory is the directory with your executable, you can call

Code: Select all

SetCurrentDirectory(GetPathPart(ProgramFilename()))
at the top of your program.

Re: Executable folder location

Posted: Sat Feb 18, 2023 3:59 pm
by Catdaddy
I can't believe I overlooked ProgramFilename(). Thank you both for pointing that out.