Announcement

Collapse
No announcement yet.

How can a PB console app find its native directory?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • How can a PB console app find its native directory?

    How can a PB console app find (from the OS) the name, at run time, of its exe file and the folder in which it resides, bearing in mind that the exe could have been renamed after compilation and that the current directory (i.e. the one you are "in" when you run the program) is not necessarily where the exe lives.

    The concept of the current directory (a DOS term) is quite relevant under Windows. It is the "Start in" or "Working" folder specified in the properties of the shortcut used to run the exe file. (It does NOT have to be the folder in which the application file resides, and sometimes SHOULD NOT be.)

    Some years ago, I wrote a calendar program in PB 3.1 for DOS (all I had back then), which included the following advice to users in the installation instructions:

    On a computer that is shared by several people, even if they all share a single user account, each person can customise Calendar with their own preferred colour scheme and their own personal set of diary entries without affecting any other person's use of Calendar. Just copy the files Colors.txt and UserData.txt to a personal folder of your own choice, then make your own shortcut for Calendar, and in the shortcut's properties, specify that folder as the "working" or "start in" folder. You can then edit your own private copies of Colors and UserData to personalise Calendar according to your own preferences.

    However, the program also uses other ancillary files that are not specific to individual users. Logically, there should only be a single set of those files and they should reside in the application's folder, and the app should read them from that folder even if a different "start in" folder is specified in the properties of the app's shortcut.

    With PB for DOS, I was able to identify the program's native directory and its exe name at run time by: (a) calling DOS interrupt 21/62 to find the program's PSP address, (b) finding, in the PSP, a pointer to the program's environment block, and (c) finding, just beyond the end of the env't table, after a pair of bytes ASCII 1,0, the pathname by which the program was invoked, which is stored at that memory location by DOS when it loads the program into memory.
    (BTW, in case anyone is interested in the specifics of this, I am attaching the source code for it, which is extensively documented.)

    I now want to port the program to Wndows as a console app. Is there a technique that can be used in PBCC (I am using version 3.04) to get the same information from Windows?

    Attached Files
    Last edited by Mottel Gutnick; 14 Jan 2009, 01:23 AM. Reason: uploaded an updated version of the attchment (minor corrections)

  • #2
    For folder where EXE is run from:

    Code:
    local wx as asciiz*%max_path
    getmodulefilename %null, wx, sizeof(wx)
    'wx will contain complete file/path name of EXE running
    For current 'working folder':

    Code:
    local wx as asciiz*%max_path
    getcurrentdirectory wx, sizeof(wx)
    'wx will contain current working directory - this is NOT necessarily the same thing as a DOS 'current directory'!
    Both 'GetModuleFileName()' and 'GetCurrentDirectory()' are Windows API's. Normally, you would use #INCLUDE "win32api.inc" so you can call them.

    Comment


    • #3
      If you are a PB/CC 5 user, look up "EXE" in the documentation
      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

      Comment


      • #4
        Tnanks (but note correction)

        Thanks Clay,
        It took a while for me to get it working, but it works now.
        (Never done any API calls before -- I must bone up on this.)

        Note: you had the arguments to GetCurrentDirectory in the wrong order.

        In what way is the current dir in Windows different from the same
        concept in DOS (at least for the execution life of the Windows' exe)?

        Code:
        ' Compiled with Power Basic Console Compiler 3.04 for Windows
        
        ' Thanks to Clay Clear:
        ' http://www.powerbasic.com/support/pbforums/showthread.php?t=39566
        
        ' This was compiled to an exe file in the folder named just below (in the
        ' COMPILE directive), then a Desktop shortcut was created for it, in whose
        ' properties the "Start in" folder is specified as D:\My\Code. output is:
        
        ' My own pathname = 'C:\Bin\GetDirs.exe'    Length = 18
        ' Current Directory = 'D:\My\Code'          Length = 10
        ' Press any key to end ...
        
        
        #COMPILE EXE "C:\Bin\GetDirs.exe"
        #INCLUDE "win32api.inc"
                 ' %MAX_PATH  = 260  (max. length of full pathname)
                 ' %Max_Dir, %Max_FName and %Max_Ext are all 256
        
        sub MainProc
        '   --------
        '   From:  pbmain
        '   Calls: API functions GetModuleFilename and GetCurrentDirectory
        
            local Length1&, Length2&, MyPathName$, CurrentDirectory$, _
                  wx1 as asciiz*%max_path, wx2 as asciiz*%max_path
        
            ' wx1 will contain complete pathname of EXE running
            Length1& = GetModuleFilename %null, wx1, sizeof(wx1)
            MyPathName$ = wx1
        
            ' wx2 will contain current working directory
            ' this is NOT necessarily the same thing as a DOS 'current directory'!
             Length2& = GetCurrentDirectory sizeof(wx2), wx2
             CurrentDirectory$ = wx2
        
            print "My own pathname = '"    MyPathName$ "'"        ,"Length =" Length1&
            print "Current Directory = '"  CurrentDirectory$ "'"  ,"Length =" Length2&
        end sub  ' MainProc -------------------------------------------------
        
        
        function pbmain
        '        ------
            local i$
        
            call MainProc
            print "Press any key to end ..."
            i$ = waitkey$  ' Wait for keypress
        end function  ' pbmain ----------------------------------------------

        Comment


        • #5
          ... and thanks Kev. I don't have CC5, but I just checked the new features of ver 5 on the products webpage and I see what you mean. I'm still using 3.04 (with the exchange rate of the Aussie dollar what it is now, I can't afford to upgrade), so it's good to have found another way of getting the relevant info from Windows (thanks to Clay having pointed me in the right direction).

          Comment


          • #6
            If I recall from my DOS programming days, the DOS 'current dir' is a system-wide thingy. Under Win32 (I don't know about Win64), the 'current' [aka 'working'] directory is exactly that - the current working directory for the application (i.e., not system wide).

            Comment


            • #7
              In what way is the current dir in Windows different from the same
              concept in DOS (at least for the execution life of the Windows' exe)?
              It's exactly the same... it is the location of files whose names are specified either without a path name or with a relative pathname. (the ".\" folder, if you will).

              BTW in either case it's for the life of the program *or* until the program changes the current directory. (CHDIR statement in BASIC).

              Under DOS it 'seems' system-wide because there is no such thing as multiple processes.
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment


              • #8
                > ...any API calls before -- I must bone up on this.

                Yes.
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment

                Working...
                X