Announcement

Collapse
No announcement yet.

Determine current drive?

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

  • Determine current drive?

    I feel like an idiot for asking such simple questions... but
    here goes..

    I have a need to determine the current drive that my application
    is being run from. The directory path is unimportant, I'm
    obtaining that from the PB CURDIR$ function. How can I do
    this with an API call (and does anyone have a quick code
    example)?



    ------------------

  • #2
    Msgbox "I'm on Drive: " & Left$(AppPath,2)

    Code:
    Function AppPath() Export As String
        Local zTmp As Asciiz * 256
        Local sTmp As String
        LenExeName& = GetModuleFileName(ByVal %NULL, zTmp, SizeOf(zTmp))
        If LenExeName& Then
           LenExeName& = Min&(LenExeName&, SizeOf(zTmp))
           sTmp = Left$(zTmp, LenExeName&)
           sTmp = Left$(sTmp,Instr(-1,sTmp,"\"))
           Function = sTmp
        End If
    End Function
    ------------------
    Scott
    Scott Turchin
    MCSE, MCP+I
    http://www.tngbbs.com
    ----------------------
    True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

    Comment


    • #3
      Much simpler:

      CurrentDriveLetter$ = LEFT$(CurDir$, 1)




      ------------------
      Clay C. Clear

      http://www.v3space.com/a/a39/202/

      [email protected]

      Comment


      • #4
        Hmmm....
        Think a bit about it guys....
        and you will notice that your advice only works in some cases...
        --
        Ariel, code supplied will get you the local drive (mapped or not) or the network share
        if your application is started from an UNC-path.
        A friendly advice, I think your approach to get app-path via PB function
        CURDIR$ is a bad idea. It might work but mostly not...
        --
        Code:
        #Include "Win32api.inc"
        Function FSO_AppRoot()As String
        Local l&,Buffer$,Tmp$,FS$,SH$
        Buffer$=Space$(500)
          L& = GetModuleFileName(%NULL, _
                                 ByVal StrPtr(Buffer$), _
                                 ByVal Len(Buffer$))
          If L& = %NULL Then Function = "":Exit Function
        '--apppath and appame in Buffer$-----------------
          Buffer$=UCase$(Left$(Buffer$,L&))
          If (Mid$(Buffer$,1,1)>= "A" And _
              Mid$(Buffer$,1,1)<="Z") And _
              (Mid$(Buffer$,2,1)=":") Then
           Function = Mid$(Buffer$,1,2) & "\"
          ElseIf Mid$(Buffer$,1,2)="\\" Then
           FS$ = Rtrim$(Parse$(Buffer$,"\",3))
           SH$ = Rtrim$(Parse$(Buffer$,"\",4))
           If Len(FS$)< 2 Then Function = "":Exit Function
           Buffer$ = "\\" & FS$ & "\"
           If Len(SH$) < 1 Then Function = Buffer$:Exit Function
           Function = Buffer$ & SH$ & "\"
          Else
           Function = ""
          End If
        End Function
        Function PbMain()As Long
          Print fso_AppRoot()
          waitkey$
        End Function
        ------------------
        Fred
        mailto:[email protected][email protected]</A>
        http://www.oxenby.se



        [This message has been edited by Fred Oxenby (edited July 14, 2001).]
        Fred
        mailto:[email protected][email protected]</A>
        http://www.oxenby.se

        Comment


        • #5
          Ariel,

          Use Fred's approach! After his reply, I did some further testing of
          CURDIR$ and GetCurrentDirectory, and he's absolutely correct - they
          are NOT always successful (read "accurate")! His approach, however,
          worked in the test program I wrote. The same test program failed when
          using CURDIR$ and GetCurrentDirectory.




          ------------------
          Clay C. Clear

          [email protected]

          http://www.v3space.com/a/a39/202/ (currently inactive)

          Comment


          • #6
            Clay, in what way is CURDIR$ "not very accurate"? Please explain your findings in detail.

            Please be aware that the current folder is not guaranteed to be the same folder that the EXE resides in.

            Further, Windows itself may do something unexpected when an EXE is launched from a UNC path - often the current folder will be set to "C:\" or similar.

            However, even in this case, the current folder reported by CURDIR$ will still be 100% accurate - the current folder will actually be "C:\". Your statement suggesting "inaccuracy" is inaccurate!




            ------------------
            Lance
            PowerBASIC Support
            mailto:[email protected][email protected]</A>
            Lance
            mailto:[email protected]

            Comment


            • #7
              Lance,

              The test program I used I ran with Start | Run. The test program
              was in a folder that's in my DOS Path. CURDIR$ returned
              "C:\WINDOWS\Desktop" when I ran the program by only specifying
              the program name. It was accurate when I specified the full path
              to the program. Fred's code was accurate in BOTH instances. In
              both cases, it returned the folder that the program was actually
              run from.

              Clear as Clay?

              I don't agree with your statement about my "inaccurate" comment.
              The online Help should specifically state that Windows may
              alter the "current directory" when using CURDIR$; otherwise,
              programmers may be "mislead."

              BTW, I haven't read the online Help regarding the CURDIR$ statement
              in AGES - I'll go read it right now - maybe it DOES make that
              qualification (then I'll have to "eat my words" <grin> )


              ------------------
              Clay C. Clear

              [email protected]
              http://www.v3space.com/a/a39/202/ (currently inactive)

              [This message has been edited by Clay Clear (edited July 14, 2001).]

              Comment


              • #8
                I didn't realize that the drive was saved with CURDIR$ ....

                The only reason I need to do this is because I've found when I
                use the API directory browse command it changes my current path,
                and that is a problem for the application I'm working on.

                Thanks for the help!


                ------------------

                Comment


                • #9
                  Clay,

                  Ok, that explains it clearly - you wanted the app-folder rather than the current-path... CURDIR$ returns the current folder, not the app folder, hence the need for GetModuleFilename().

                  ------------------
                  Lance
                  PowerBASIC Support
                  mailto:[email protected][email protected]</A>
                  Lance
                  mailto:[email protected]

                  Comment


                  • #10
                    Ariel --

                    > I've found when I use the API directory browse
                    > command it changes my current path,

                    Yes, several APIs such as GetOpenFileName do that, and it can be a problem. But usually only for mutli-threaded applications. Have you tried using the OFN_NOCHANGEDIR flag, or whatever the equivalent flag is for the API that you are using? That makes sure that the current directory is reset when the select-file dialog closes.

                    If your app is multi-threaded that's a different story, because OFN_NOCHANGEDIR does not keep the currently directory from changing while the dialog is being displayed, and the change affects all threads of the current app.

                    -- Eric


                    ------------------
                    Perfect Sync Development Tools
                    Perfect Sync Web Site
                    Contact Us: mailto:[email protected]om[email protected]</A>
                    "Not my circus, not my monkeys."

                    Comment


                    • #11
                      Lance,

                      We're both correct. I just read the online Help for CURDIR$, and it
                      specifically says that it returns the "...current folder...for the
                      specified drive..."

                      So, I'm eating humble pie, right now. <chuckle>

                      Ariel,

                      Use Fred's code, because if you use CURDIR$, it might return
                      erroneous results as far as YOUR needs.


                      ------------------
                      Clay C. Clear

                      [email protected]

                      http://www.v3space.com/a/a39/202/ (currently inactive)

                      Comment


                      • #12
                        My application only uses one form that pops up.. the user selects
                        an option with a radio button, then is asked to select a
                        directory. The problem is, after the directory is selected,
                        the path needs to be set back to the application directory. I
                        have tried using CurDIR$ to get the drive letter and path, but
                        when I use CHDRIVE and CHDIR to return to the directory, it
                        is not working UNLESS I locate the program on the same drive as
                        the folder being selected.

                        So... if I could avoid this odd behavior that would be great.
                        How do I use the OFN_NOCHANGEDIR function ?


                        Originally posted by Eric Pearson:
                        Ariel --

                        > I've found when I use the API directory browse
                        > command it changes my current path,

                        Yes, several APIs such as GetOpenFileName do that, and it can be a problem. But usually only for mutli-threaded applications. Have you tried using the OFN_NOCHANGEDIR flag, or whatever the equivalent flag is for the API that you are using? That makes sure that the current directory is reset when the select-file dialog closes.

                        If your app is multi-threaded that's a different story, because OFN_NOCHANGEDIR does not keep the currently directory from changing while the dialog is being displayed, and the change affects all threads of the current app.

                        -- Eric




                        ------------------

                        Comment


                        • #13
                          The only reason I need to do this is because I've found when I
                          use the API directory browse command it changes my current path,
                          and that is a problem for the application I'm working on.
                          Although I started using this method before I started programming Windows applications, things like GetOpenFileName convinced me I made the correct decision a long time ago: I always store allfile names using their fully-qualified pathnames. That it way nevermatters what the current directory is.

                          MCM


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

                          Comment


                          • #14
                            > How do I use the OFN_NOCHANGEDIR function ?

                            If you are using the GetOpenFile API, you would use %OFN_NOCHANGEDIR in the Flags element of the OPENFILENAME structure.

                            Which API is causing this problem for you?

                            -- Eric

                            ------------------
                            Perfect Sync Development Tools
                            Perfect Sync Web Site
                            Contact Us: mailto:[email protected][email protected]</A>
                            "Not my circus, not my monkeys."

                            Comment


                            • #15
                              Michael - I understand what you're saying, but it's not possible
                              in this application.

                              Eric - I am using SHBrowseForFolder and SHGetPathFromIDList to
                              allow the user to select a path. I am using the code that has
                              been posted many times in this forum for selecting a folder.

                              Comment


                              • #16
                                As far as I know, SHBrowseForFolder does not support an option similar to OFN_NOCHANGEDIR. Oh well, it was worth a shot.

                                -- Eric

                                ------------------
                                Perfect Sync Development Tools
                                Perfect Sync Web Site
                                Contact Us: mailto:[email protected][email protected]</A>
                                "Not my circus, not my monkeys."

                                Comment


                                • #17
                                  A friendly advice, I think your approach to get app-path via PB function
                                  CURDIR$ is a bad idea. It might work but mostly not...

                                  it's a VERY bad idea.
                                  What if I click Start->Run and type the app name in?
                                  Guess what Curdir$ is??? It's C:\


                                  I had a huge headache over this, but Apppath *always* works, even on UNC if I am not mistaken...(Seems to have worked so far.)

                                  It's like 9 lines of code and quite efficient, doesn't make much sense to go beyond that...



                                  ------------------
                                  Scott
                                  Scott Turchin
                                  MCSE, MCP+I
                                  http://www.tngbbs.com
                                  ----------------------
                                  True Karate-do is this: that in daily life, one's mind and body be trained and developed in a spirit of humility; and that in critical times, one be devoted utterly to the cause of justice. -Gichin Funakoshi

                                  Comment


                                  • #18
                                    Well here is the problem I'm having now.

                                    I start my application, and pop CURDIR$ into a global variable.
                                    The user selects a directory, then I CHDRIVE and CHDIR back to
                                    the original CURDIR$ value (I've verified that it's working by
                                    doing a MSGBOX CURDIR$). Now, I need to shell out to another
                                    program - but the problem is that my system locks up after
                                    I do that if the drive letter that the user selects is
                                    different from the application drive letter.... If I don't
                                    do any directory selecting, it works fine. What the heck is
                                    going on? I've verified that it's resetting the path
                                    correctly.

                                    Unfortunately I can't provide an explicit path to the program
                                    that I'm SHELLing to; it has to be in the same directory as
                                    the application.

                                    Does anyone have an idea ?

                                    Comment


                                    • #19
                                      Are you restoring the current path after the SHELL? Are you using the Synchronous SHELL statement or Asynchronous SHELL function?

                                      What about if you SHELL to another app (just for testing, say PBEDIT.EXE) - does that make any difference?

                                      Maybe we need to see the code...

                                      Also, using shBrowseForFolder() does not change the current directory, which is why it does not have a "OFN_NOCHANGEDIR"-like setting.

                                      Try this code to pick up the directory change:

                                      (this code is closely based on code posted to this BBS)
                                      Code:
                                      #COMPILE EXE
                                      #INCLUDE "WIN32API.INC"
                                       
                                      DECLARE SUB CoTaskMemFree LIB "ole32.dll" ALIAS "CoTaskMemFree" (BYVAL hMem AS LONG)
                                       
                                      %BFFM_INITIALIZED  = 1
                                      %BFFM_SELCHANGED   = 2
                                      %BFFM_ENABLEOK     = %WM_USER + 101
                                      %BFFM_SETSELECTION = %WM_USER + 102
                                      %BIF_RETURNONLYFSDIRS  = &H0001
                                      %BIF_DONTGOBELOWDOMAIN = &H0002
                                      %BIF_RETURNFSANCESTORS = &H0008
                                      %BIF_EDITBOX           = &H0010
                                      %BIF_NEWDIALOGSTYLE    = &H0040
                                      %BIF_USENEWUI          = %BIF_NEWDIALOGSTYLE OR %BIF_EDITBOX
                                       
                                      CALLBACK FUNCTION BrowseForFolderProc
                                          IF CBMSG = %BFFM_INITIALIZED THEN
                                              DIALOG SEND CBHNDL, %BFFM_SETSELECTION, %TRUE, CBLPARAM
                                          ELSEIF CBMSG = %BFFM_SELCHANGED THEN
                                              DIM zBuffer AS ASCIIZ * %MAX_PATH
                                              CALL SHGetPathFromIDList(BYVAL CBWPARAM, zBuffer)
                                              IF ISFALSE CBWPARAM OR _                        ' No id number
                                                ISFALSE LEN(zBuffer) OR _                     ' No name
                                                ISFALSE (GETATTR(zBuffer) AND %SUBDIR) OR _   ' Not a real subdir
                                                MID$(zBuffer,2,1) <> ":" THEN                 ' Not a local or mapped drive
                                                  DIALOG SEND CBHNDL, %BFFM_ENABLEOK, %FALSE, %FALSE
                                                  BEEP
                                              ELSEIF (GETATTR(zBuffer) AND %SYSTEM) AND RIGHT$(zBuffer,2) <> ":\" THEN 
                                                  ' exclude system folders, allow root directories
                                                  DIALOG SEND CBHNDL, %BFFM_ENABLEOK, %FALSE, %FALSE
                                                  BEEP
                                              END IF
                                          END IF
                                      END FUNCTION
                                       
                                      FUNCTION BrowseForFolder(hWnd AS LONG, Title AS STRING, StartFolder AS STRING) AS STRING
                                          LOCAL zBuffer    AS ASCIIZ * %MAX_PATH
                                          LOCAL bi         AS BROWSEINFO
                                          LOCAL lpIDList   AS LONG
                                          LOCAL result     AS LONG
                                       
                                          bi.hWndOwner    = hWnd
                                          bi.lpszTitle    = STRPTR(Title)
                                          bi.ulFlags      = %BIF_RETURNONLYFSDIRS OR %BIF_DONTGOBELOWDOMAIN OR _
                                                            %BIF_USENEWUI OR %BIF_RETURNFSANCESTORS
                                          bi.lpfnCallback = CODEPTR(BrowseForFolderProc)
                                          bi.lParam       = STRPTR(StartFolder)
                                          lpIDList        = SHBrowseForFolder(bi)
                                       
                                          IF ISTRUE lpIDList AND SHGetPathFromIDList(BYVAL lpIDList, zBuffer) THEN
                                              FUNCTION = zBuffer
                                              CoTaskMemFree lpIDList
                                          END IF
                                      END FUNCTION
                                       
                                      FUNCTION PBMAIN
                                          MSGBOX BrowseForFolder(%HWND_DESKTOP, "Choose path to use:", CURDIR$)
                                      END FUNCTION

                                      ------------------
                                      Lance
                                      PowerBASIC Support
                                      mailto:[email protected][email protected]</A>
                                      Lance
                                      mailto:[email protected]

                                      Comment


                                      • #20
                                        BrowseforFolder is doing some screwy things... after I use it I
                                        have to specify explicit paths... otherwise the files I write
                                        to end up in limbo somewhere...! Try it for yourself.


                                        ------------------

                                        Comment

                                        Working...
                                        X