Announcement

Collapse

Maintenance

The forum could be offline for 30-60 minutes in the very near future for maintenance (said 3pm Pacific). I was behind on getting this notice. I do apologize.
See more
See less

Convert relative path to abolute path?

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

  • Michael Mattias
    replied
    Here is what I did...
    Code:
    ' NEW FUNCTION VERSION 2.1
    ' Returns: FALSE = NO ERRORS
    ' TRUE = one or more errors
    FUNCTION EditCustPath (szInFileNameExt AS ASCIIZ, cfg() AS CONFIGFileType) AS LONG
    ' for any config file entry with a custPath column, make that column the new file name
    ' which is the path specified in the cfg.szPath + szInfileNameExt
    ' and make sure I can write it.
    ' How do I allow for relative paths, which I want to convert to absolute full paths?
    ' GetLongPathName? that just might do it IT DOES NOT BUT Get**FULL**Pathname works good
    
    
    ' I think I will call this with some prompts as a test program.
     LOCAL sz AS ASCIIZ * %MAX_PATH
     LOCAL szFullPath AS ASCIIZ * %MAX_PATH
     LOCAL dwAddr     AS DWORD
     LOCAL iRET AS LONG
     LOCAL iVF  AS LONG
     LOCAL swChar   AS STRING
     LOCAL LE  AS LONG
     LOCAL iCfg AS LONG
     ' GETFULLPATHNAME works perfectly even with multiple nodes!!!
     ' See also PathResolve()
     LOCAL bErr AS LONG  ' set to true as soon as any error occurs
     
     FOR iCfg = LBOUND(cfg,1) TO UBOUND (cfg,1)
          sz  = Cfg(icfg).szPath    ' what was loaded from config file
          STDOUT USING$ ("Checking config File entry # _, Path is '&'", iCfg +1&, sz)
          IF LStrLen(sz)  THEN      ' if one was found
            ' get the fully-qualified name, we need that for multiple purposes
          ' Is it a valid folder?
            RESET    szFullPath
            iRet =   GetFullpathName ( sz, SIZEOF(szFullPath), szFullPath, dwAddr)  ' returns TRUE on success
            LE = getLastError
            IF ISTRUE iREt THEN    ' we got the full name back
              iRet = %ERROR_SUCCESS  ' what we use later
              STDOUT USING$ ("  Fully Qualified Path is '&'", szFullPath)
              ' is this an existing valid folder?
              ivf  =  IsValidFolder (szFullPath)
              IF ISTRUE ivf THEN
                   STDOUT "   This is an existing folder"
              ELSE
                   STDOUT "   Folder not found; will attempt to create it."
                   swChar =  UCODE$(szFullPath) & CHR$(0,0)   ' make sure it's Unicode terminated
                   iRet    = ShCreateDirectory (GetDesktopWindow(), BYVAL STRPTR(swChar))  ' returns 0 ERROR_SUCCESS
                   IF iRet = %ERROR_SUCCESS THEN
                        STDOUT "   Folder successfully created"
                   ELSE
                        STDOUT  USING$("   Could not create folder '&'", szFullPath)
                        STDOUT         "   See STDERR for details"
                        STDERR2 USING$("   Error message is &", SystemErrorMessageText(iRet))
                        bErr        =  %TRUE
                   END IF
              END IF
                        
            ELSE
                 STDOUT USING$("   Could not get full-qualified path name for '&'", sz)
                 STDOUT USING$("   Error message is &", SystemErrorMEssageText(LE))
                 bERR        = %TRUE
            END IF
            IF ISFALSE Iret THEN  ' everyting was OK
                 ' make the cfg entry = path + Input file name
                 cfg(iCfg).szpath =  szFullPath & "\" & szInFileNameExt
                 STDOUT USING$ ("   Set Customer file name to '&'", cfg(iCfg).szPath)
            END IF
            
        END IF ' if customer even had a path entry in the config file
        
     NEXT iCfg
     
     ' ** LOGIcAL END OF FUNCTION **
     FUNCTION = bErr
    
    #IF 0
       THIS IS TEST CODE ONLY             ' change cfg entry to be input file
      DO
           STDOUT USING$ ("CURDIR$==>'&'", CURDIR$)   ' does not return trailing slash
           LINE INPUT "Enter cust Path to convert", sz
           IF LEN (sz) THEN
    
                RESET  szFullPath
                IF ISFALSE IVF THEN
                     s = sz
                     STDOUT USING$("Pathnames for path &", PATHNAME$(PATH, s))
    
    
    
                     STDOUT USING$ ("   Creating folder '&'", s)
                    ' sWChar =  UCODE$(s) & CHR$(0,0)
    
                   
                     ' this needs fully-qualified path
                     MKDIR  s   ' fails with multiple nodes.Ok wioth A\DAta as long as A exists.
                     'STDOUT "Create Folder Returns " & SystemErrorMEssageText(iret)
                END IF
           ELSE
                EXIT FUNCTION
           END IF
      LOOP
    #ENDIF
    
    
    END FUNCTION
    Probably more than you wanted to know, but hey, what the heck.

    MCM

    Leave a comment:


  • George Bleck
    replied
    This do what you need?

    Code:
    #INCLUDE "win32api.inc"
     
    '----------------------------------------------------------------------------(')
     
    FUNCTION RealPath( strSource AS STRING ) AS STRING
     LOCAL strTargetEES AS STRING
     LOCAL strTargetGFMN AS STRING
     LOCAL lngReturnedLen AS LONG
     LOCAL strBuffer AS STRING
     LOCAL pFilePart AS DWORD
     ' Expand any environment strings first
     strTargetEES = SPACE$( %MAX_PATH + 1 )
     lngReturnedLen = EXPANDENVIRONMENTSTRINGS( BYCOPY strSource, BYVAL STRPTR( strTargetEES ), LEN( strTargetEES ))
     ' did EES work?
     IF lngReturnedLen THEN
      ' Expand to a full path
      strTargetEES = LEFT$( strTargetEES, lngReturnedLen - 1 )
      strBuffer = SPACE$( %MAX_PATH + 1 )
      lngReturnedLen = GETFULLPATHNAME( BYCOPY strTargetEES, LEN( strBuffer ), BYVAL STRPTR( strBuffer ), pFilePart )
      ' did GFPN work?
      IF lngReturnedLen THEN
       FUNCTION = LEFT$( strBuffer, lngReturnedLen )
      ELSE
       FUNCTION = "Error on GFPN"
      END IF
     ELSE
      FUNCTION = "Error on EES"
     END IF
    END FUNCTION
     
    '----------------------------------------------------------------------------(')
     
    FUNCTION PBMAIN( )
     MSGBOX RealPath( "%TEMP%" )
     MSGBOX RealPath( "%TEMP%\.." )
     MSGBOX RealPath( "%TEMP%\.." )
    END FUNCTION
    BTW, an important threading note about GetFullPathName from the MSDN docs (http://msdn.microsoft.com/en-us/library/aa364963.aspx)...

    Multi-threaded applications and shared library code should should not use the GetFullPathName function. The current directory state written by the SetCurrentDirectory function is stored as a global variable in each process, therefore multi-threaded 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 SetCurrentDirectory and GetCurrentDirectory functions.
    Last edited by George Bleck; 9 Jun 2009, 01:20 PM.

    Leave a comment:


  • Michael Mattias
    replied
    >Path functions are already provided by Windows

    Duh, how about this one...

    PathResolve Function

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

    Converts a relative or unqualified path name to a fully-qualified path name.
    Sounds pretty close to what I wanted, huh?

    Leave a comment:


  • Kev Peel
    replied
    Path functions are already provided by Windows and defined in SHLWAPI.INC > PathXX functions (particularly PathRelativePathTo)

    Leave a comment:


  • Michael Mattias
    replied
    Thanks for the tips, they got me where I needed to be.

    You are going to love what my problem was....

    I was trying to make this work using GetLongPathname instead of GetFullPathName.

    I can now attest from personal experience they are in fact two different functions and they do not work the same way.

    MCM

    Leave a comment:


  • Scott Slater
    replied
    Are you looking for something like this?

    Code:
    Function ReturnFullPath(ByVal PathStr As String, Optional ByVal UseProgramDirectory As Dword) As String
       
       Local StartDir  As String
       Local WorkDrive As String
       Local PthSegmnt As String
       Local sWork     As String
       Local idx       As Dword
       Local idx2      As Dword
       
       If UseProgramDirectory Then
          StartDir = EXE.Path$
       Else
          StartDir = CurDir$
       End If
       
       StartDir = RTrim$(StartDir, "\") ' remove any trailing backslashes
       
       If Mid$(PathStr,2,2) = ":\" Then
          StartDir = PathStr
          StartDir = RTrim$(StartDir, "\")
          WorkDrive = Left$(StartDir, 3)
          PathStr = Mid$(StartDir,4)
          StartDir = ""
       Else
          WorkDrive = Left$(StartDir, 3)
          StartDir = Mid$(StartDir, 4)
       End If
       
       For idx = 1 To ParseCount(PathStr, "\")
          PthSegmnt = Parse$(PathStr, "\", idx)
          If PthSegmnt = ".." Then ' Back one
             If Len(StartDir) Then
                sWork = ""
                For idx2 = 1 To ParseCount(StartDir, "\") - 1
                   sWork &= "\" & Parse$(StartDir, "\", idx2)
                Next idx2
                StartDir = Trim$(sWork, "\")
             End If
          ElseIf idx =1 And PthSegmnt = "" Then
             StartDir = ""
          ElseIf (PthSegmnt <> ".") And (PthSegmnt <> "") Then
             StartDir &= "\" & PthSegmnt
             StartDir = Trim$(StartDir, "\")
          End If
       Next idx
       
       Function = WorkDrive & StartDir
       
    End Function
    Last edited by Scott Slater; 9 Jun 2009, 10:30 AM.

    Leave a comment:


  • José Roca
    replied
    Code:
    LOCAL dwLen AS DWORD
    LOCAL szBuffer AS ASCIIZ * %MAX_PATH
    dwLen = GetFullPathName(".\data\smith", %MAX_PATH, szBuffer, BYVAL %NULL)

    Leave a comment:


  • Erich Schulman
    replied
    http://docs.activestate.com/activepy...Name_meth.html shows there is a Python function for that. So maybe studying the Python Win32 extensions source code would give a clue.

    Leave a comment:


  • Michael Mattias
    replied
    Here's as couple of functions I use once I have a fully-qualified file or folder name. Maybe these will give someone an idea to solve my direct problem....

    IsValidFolder requires the folder exist (and works with relative folders)
    IsValidOutfileName does not.

    Code:
    FUNCTION IsValidFolder (szPath AS ASCIIZ) AS LONG
    
      LOCAL  FA AS LONG
    
      FA         = GetFileAttributes(szPath)
      'MSGBOX "FA=" & HEX$(FA,8) & $CRLF & szPath
      IF FA = -1& THEN
          FUNCTION = 0
      ELSE
         FUNCTION = (FA AND %FILE_ATTRIBUTE_DIRECTORY) = %FILE_ATTRIBUTE_DIRECTORY
      END IF
    
    END FUNCTION
    
    ' FIXED. A Wildcard here is automatically an invalid output file name
    FUNCTION IsValidOutFileName(szFN AS ASCIIZ) AS LONG
        ' see if a file name is valid by trying to open it
        ' returns true if we can create the file...or if it already exists else false
    
        LOCAL hFile AS LONG, E AS LONG, fs AS LONG
        LOCAL iPos AS LONG
    
    
        iPos = INSTR (szFN, ANY "?*")
        IF ISTRUE iPos THEN
            FUNCTION = %FALSE
            EXIT FUNCTION
        END IF
    
        IF DIR$(szFn) <> "" THEN  ' file exists, so the name must be valid
            FUNCTION  = -1&
            EXIT FUNCTION
        END IF
    
        hFile = FREEFILE
        OPEN szFN FOR BINARY AS hFILE
        E = ERRCLEAR
        'MSGBOX "E on open of " & szfn & " =" & STR$(E)
        IF ISFALSE E THEN
            fs = LOF(hFile)
            CLOSE hFile
            IF fs = 0 THEN   ' we just created it...empty..
               KILL szFN
            END IF
        END IF
        FUNCTION = (E=0)
    END FUNCTION
    MCM
    Last edited by Michael Mattias; 9 Jun 2009, 08:47 AM.

    Leave a comment:


  • Michael Mattias
    started a topic Convert relative path to abolute path?

    Convert relative path to abolute path?

    I have been working on a project for a client in which the configuration file is is to support a series of "folder names" to direct certain outputs.

    I would like to support relative paths such as ...

    .\data\smith << would be same as 'data\smith'
    or
    ..\data\smith << would not be the same.

    I was working with a number of WinAPI and intrinsic PB functions yesterday and could not find the magic combination which would convert these relative paths to fully-qualified absolute paths... eg
    If currrent directory is "d:\RB835" then

    .\data\smith ==> d:\RB835\data\smith

    ..\data\smith ==> D:\data\smith


    Does anyone have any good ideas for converting these "dot" and "dot-dot" entries from the relative form to the absolute form?

    I also want to support entry of absolute paths; but I think I can just identify these as those starting with either "x:\" [fully qualified] or just "\" [current drive assumed]

    OOPS forgot....

    The named path may or may not exist at the time it is checked... at which time I have to create it.

    ShCreateDirectory() works great (handles any 'missing' subdirectories automatically) , but that requires a fully-qualified path, which is why I am trying to get the absolute path name.

    Thanks
    Last edited by Michael Mattias; 9 Jun 2009, 08:40 AM.
Working...
X