Announcement

Collapse
No announcement yet.

Test for Valid File Name String

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

  • Test for Valid File Name String

    Is there an API to test if a string can be used to rename a file - i.e., the string would be valid file name?

    I would rather do this:

    Code:
    iResult = IsValidFileNameString(FileName$)
    than try to convert this to code ...

    From MSDN's "Naming a File or Directory," here are the general conventions for what a legal file name is under Windows:

    You may use any character in the current code page (Unicode/ANSI above 127), except:< > : " / \ | ? *
    • Characters whose integer representations are 0-31 (less than ASCII space)
    • Any other character that the target file system does not allow (say, trailing periods or spaces)
    • Any of the DOS names: CON, PRN, AUX, NUL, COM0, COM1, COM2, COM3, COM4, COM5, COM6, COM7, COM8, COM9, LPT0, LPT1, LPT2, LPT3, LPT4, LPT5, LPT6, LPT7, LPT8, LPT9 (and avoid AUX.txt, etc)
    • The file name is all periods

    Some optional things to check:
    • File paths (including the file name) may not have more than 260 characters (that don't use the \?\ prefix)
    • Unicode file paths (including the file name) with more than 32,000 characters when using \?\ (note that prefix may expand directory components and cause it to overflow the 32,000 limit)
    I could do a function like this - attempting to create a file using the string - but I was hoping there was an available API to do it for me.

    Code:
    Function IsValidFileNameString(fName$) As Long
    On Error GoTo Failure
       Open fName$ For Output As #1
       Close #1
       Function = 1
       Kill fName$
       Exit Function
    Failure:
    End Function

  • #2
    No. Because there is no standard set of rules for it.
    https://docs.microsoft.com/en-us/win.../naming-a-file

    "All file systems follow the same general naming conventions for an individual file: a base file name and an optional extension, separated by a period. However, each file system, such as NTFS, CDFS, exFAT, UDFS, FAT, and FAT32, can have specific and differing rules about the formation of the individual components in the path to a directory or file."

    Comment


    • #3
      Hey Gary,

      I would take this by the other end.
      Instead of checking if it could be done then do it if all is fine,
      I woud do it and check if the operation was successfull.

      PB syntax-
      ERRCLEAR
      NAME sSourceFile AS sDestFile
      IF ERR = %ERR_BADFILENAME THEN...
      IF ERR = %ERR_FILEALREADYEXISTS THEN...

      SDK-
      RetVal = MoveFile(sSourceFile, sDestFile)
      LastError = GetLastError()
      IF LastError = %ERROR_INVALID_NAME THEN...
      IF LastError = %ERROR_ALREADY_EXISTS THEN...

      Comment


      • #4
        There might be an indirect way via the PathCleanupSpec API function (defined in ShlObj.inc).

        Removes illegal characters from a file or directory name. Enforces the 8.3 filename format on drives that do not support long file names.
        If the file name passed is altered, then it's not a valid file name.

        Comment


        • #5
          Howdy, Pierre!
          Well, I should have said both creating and renaming a file. The small function I put in the OP handles both. But neither of our suggestions recognizes when a file is read-only or already opened by another process.- which would give a false answer to a valid string. I can live with that limitation.

          And howdy, Knuth!
          That's a great suggestion. Here's a small function that uses your suggestion:

          Code:
          Function IsValidFileNameString(fName As WStringZ * %Max_Path) As Long
             Local temp As WStringZ * %Max_Path
             temp = fName
             PathCleanupSpec  Exe.Path$, fName
             Function = (temp=fName)
          End Function
          Hey Stuart!
          I would think the API is OS specific, so is a valid solution. Wouldn't you think so?

          Comment


          • #6
            Originally posted by Gary Beene View Post

            Hey Stuart!
            I would think the API is OS specific, so is a valid solution. Wouldn't you think so?
            The API is OS specific but storage media are not, they are diverse. What is a valid filename when writing to a CD, to a Linux NAS device, to a digital camera or android device? How does Win32 know where you want to create the file?

            Comment


            • #7
              Howdy, Stuart!

              Well, the first argument of the API is the location where the file is to be placed. But without more details from MSDN, I don't know if the API uses that to determine which media is involved in order to determine the criteria for a valid file name string. I'd expect it to do so, but haven't tested it.

              Comment


              • #8
                Hey Gary,

                As Stuart says, you may consider an api to be "OS compatible" with the system where it reside,
                but it is not the same thing as file system specific.
                You may have an OS with FAT32 and NTFS drives, etc., that obey to different rules

                There is Börje's IsValidFilePathName
                Also you may look at PathGetCharType() and PathSearchAndQualify()...

                In the case of PathCleanupSpec() notice that much more work will have to be done,
                "COM1" or "..." will be considered as good file name. And many other rules are ignored.
                It is file system specific if you specify a valid directory. See Bill's doc. for more.

                On the other hand, the MoveFile() - GetLastError() way will check everything needed
                according to the specific file system and tell you what the error is, if any.

                As I see it, the same goes for renaming or creating a file.
                Do it and check the error returned by your try, this is a reliable way.
                Getting what's going on the fly.

                A few possible situation: ERROR_INVALID_NAME, ERROR_ALREADY_EXISTS, ERROR_ACCESS_DENIED, ERROR_FILE_EXISTS,
                ERROR_FILE_NOT_FOUND, ERROR_PATH_NOT_FOUND, ERROR_TOO_MANY_OPEN_FILES, ERROR_NOT_ENOUGH_MEMORY, ERROR_INVALID_ACCESS,
                ERROR_INVALID_DRIVE, ERROR_WRITE_PROTECT, ERROR_SUCCESS, etc, etc.
                Last edited by Pierre Bellisle; 31 Oct 2019, 02:54 PM.

                Comment


                • #9
                  Seems that even CreateFile() is claiming success with a filename like "..."

                  For the fun of it, here is a isValidFileNameRW() function.
                  It should be reliable on most common situations...

                  Code:
                  #COMPILE EXE '#Win#
                  %Unicode = 1
                  #DIM ALL
                  #INCLUDE "Win32Api.inc"
                  #INCLUDE "ShlObj.inc" 'PowerBASIC
                  '#INCLUDE "AfxPath.inc" 'José
                  '_____________________________________________________________________________
                  
                  FUNCTION WinError$(BYVAL ErrorCode AS DWORD) AS STRING
                   LOCAL pwzError AS WSTRINGZ POINTER 'Max is 64K
                   LOCAL ErrorLen AS DWORD
                  
                   ErrorLen = FormatMessageW(%FORMAT_MESSAGE_FROM_SYSTEM OR %FORMAT_MESSAGE_ALLOCATE_BUFFER, _
                                             BYVAL %NULL, ErrorCode, %NULL, BYVAL VARPTR(pwzError), %NULL, BYVAL %NULL)
                   IF ErrorLen THEN
                     REPLACE $$CRLF WITH $$SPC IN @pwzError
                     FUNCTION = "Error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ") : " & @pwzError
                     LocalFree(pwzError)
                   ELSE
                     FUNCTION = "Unknown error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ")"
                   END IF
                  
                  END FUNCTION
                  '_____________________________________________________________________________
                  
                  FUNCTION PathError$(ErrorCode AS LONG)AS STRING
                   LOCAL sError AS STRING
                  
                   IF ErrorCode THEN
                     IF (ErrorCode AND %PCS_FATAL)        THEN sError &= "PCS_FATAL, "        '&H80000000???
                     IF (ErrorCode AND %PCS_REPLACEDCHAR) THEN sError &= "PCS_REPLACEDCHAR, " '&H00000001???
                     IF (ErrorCode AND %PCS_REMOVEDCHAR)  THEN sError &= "PCS_REMOVEDCHAR, "  '&H00000002???
                     IF (ErrorCode AND %PCS_TRUNCATED)    THEN sError &= "PCS_TRUNCATED, "    '&H00000004???
                     IF (ErrorCode AND %PCS_PATHTOOLONG)  THEN sError &= "PCS_PATHTOOLONG, "  '&H00000008???  Always combined with FATAL
                     FUNCTION = LEFT$(sError, -2) & " PathCleanupSpec error"
                   ELSE
                     FUNCTION = "[no error] PathCleanupSpec"
                   END IF
                  
                  END FUNCTION
                  '_____________________________________________________________________________
                  
                  FUNCTION isValidFileNameRW(BYVAL wzFileName AS WSTRINGZ * %MAX_PATH, OPTIONAL BYVAL wzPath AS WSTRINGZ * %MAX_PATH) AS LONG
                   LOCAL hFile          AS DWORD
                   LOCAL FileAttributes AS DWORD
                   LOCAL LastError      AS LONG
                   LOCAL RetVal         AS LONG
                   LOCAL CleanupError   AS LONG
                   LOCAL wzCleanUp      AS WSTRINGZ * %MAX_PATH
                  
                   'Space or dot ending filename
                   IF ASC(wzFileName, -1) = 32 OR ASC(wzFileName, -1) = 46 THEN
                     MessageBox(%HWND_DESKTOP, wzFileName & $CRLF & "Invalid ending char", _
                                "Invalid ending char", %MB_OK OR %MB_TOPMOST)
                     EXIT FUNCTION
                   END IF
                  
                   IF LEN(wzPath) THEN
                     'Add ending "\" to optionnal folder if needed
                     IF ASC(wzPath, -1) <> 92 THEN
                       wzPath &= "\"
                     END IF
                     'isFolder exist
                     IF GetFileAttributes(wzPath) AND &HFF000010??? <> %FILE_ATTRIBUTE_DIRECTORY THEN
                       MessageBox(%HWND_DESKTOP, wzPath & wzFileName & $CRLF & "Invalid folder", _
                                  "Invalid folder", %MB_OK OR %MB_TOPMOST)
                       EXIT FUNCTION
                     END IF
                   ELSE
                     'Get OS temporary path, aka C:\Users\Pierre\AppData\Local\Temp\
                     GetTempPathW(SIZEOF(wzPath) / 2, wzPath)
                   END IF
                  
                   'Clean up filename from invalid characterts
                   wzCleanUp = wzFileName 'Keep genuine intact
                   RetVal = PathCleanupSpec(wzPath, wzCleanUp) 'File system aware, PathCleanupSpec may be unavailable in the future.
                   IF RetVal THEN
                     MessageBox(%HWND_DESKTOP, wzFileName & $CRLF & wzCleanUp & $CRLF & _
                                PathError$(RetVal), "PathCleanupSpec", %MB_OK OR %MB_TOPMOST)
                     EXIT FUNCTION
                   END IF
                   'IF INSTR(wzFileName, ANY "<>:""/\|?*" & CHR$$(0)) THEN 'Invalid char, job done by PathCleanupSpec above
                   '  MessageBox(%HWND_DESKTOP, wzFileName & $CRLF & "Invalid char", "Invalid char", %MB_OK OR %MB_TOPMOST)
                   '  EXIT FUNCTION
                   'END IF
                  
                   'Reserved filename
                   SELECT CASE LCASE$(wzFileName)
                     CASE "con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", _
                          "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"
                       MessageBox(%HWND_DESKTOP, wzFileName & $CRLF & "Reserved file name", "Reserved file name", %MB_OK OR %MB_TOPMOST)
                       EXIT FUNCTION
                   END SELECT
                  
                   'Reserved filename.ext
                   RetVal = INSTR(wzFileName, ".")
                   IF RetVal THEN
                     SELECT CASE LEFT$(LCASE$(wzFileName), RetVal) 'Invalid Filename
                       CASE "con.", "prn.", "aux.", "nul.", "com1.", "com2.", "com3.", "com4.", "com5.", "com6.", "com7.", "com8.", "com9", _
                            "lpt1.", "lpt2.", "lpt3.", "lpt4.", "lpt5.", "lpt6.", "lpt7.", "lpt8.", "lpt9."
                         MessageBox(%HWND_DESKTOP, wzFileName & $CRLF & "Reserved file name.", "Reserved file name.", %MB_OK OR %MB_TOPMOST)
                         EXIT FUNCTION
                     END SELECT
                   END IF
                  
                   'Create a test file if it dosen't exist or open it if it exist
                   hFile = CreateFileW(wzPath & wzFileName, %GENERIC_READ OR %GENERIC_WRITE, _
                                       %FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, _
                                       %OPEN_ALWAYS, %FILE_ATTRIBUTE_NORMAL, 0)
                   LastError = GetLastError()
                  
                   'Does file exist
                   FileAttributes = GetFileAttributes(wzPath & wzFileName) AND &HFF000010???
                  
                   'File exist
                   IF FileAttributes = %FALSE THEN
                     MessageBox(%HWND_DESKTOP, wzPath & wzFileName & $CRLF & "Valid file name", _
                                "Valid file name", %MB_OK OR %MB_TOPMOST)
                     FUNCTION = %TRUE
                   ELSE 'File do not exist
                     MessageBox(%HWND_DESKTOP, wzPath & wzFileName & $CRLF & IIF$(LastError, WinError$(LastError), "Invalid file name") & $CRLF & _
                                HEX$(FileAttributes), "Invalid file name", %MB_OK OR %MB_TOPMOST)
                   END IF
                  
                   'File was opened
                   IF hFile <> %INVALID_HANDLE_VALUE THEN
                     CloseHandle(hFile)
                     IF LastError <> %ERROR_ALREADY_EXISTS THEN
                       'Delete newly created file
                       DeleteFile(wzPath & wzFileName)
                     END IF
                   END IF
                  
                  END FUNCTION
                  '_____________________________________________________________________________
                  
                  FUNCTION PBMAIN()
                   LOCAL isValid AS LONG
                  
                   isValid = isValidFileNameRW("Test.bas")
                   isValid = isValidFileNameRW("Test*.bas")
                   isValid = isValidFileNameRW("Test.bas" & CHR$$(10))
                   isValid = isValidFileNameRW("...")
                   isValid = isValidFileNameRW("COM9")
                   isValid = isValidFileNameRW("COM99")
                   isValid = isValidFileNameRW("COM1.txt")
                   isValid = isValidFileNameRW("TestX.bas", "X:\") 'Set an invalid drive
                   isValid = isValidFileNameRW("Test.basSpace ")
                   isValid = isValidFileNameRW("Test.basDot.")
                  
                  END FUNCTION
                  '_____________________________________________________________________________
                  '

                  Comment


                  • #10
                    Same as above without MessageBox details...

                    Code:
                    #COMPILE EXE '#Win#
                    %Unicode = 1
                    #DIM ALL
                    #INCLUDE "Win32Api.inc"
                    #INCLUDE "ShlObj.inc" 'PowerBASIC
                    '#INCLUDE "AfxPath.inc" 'José
                    '_____________________________________________________________________________
                    
                    FUNCTION isValidFileNameRW(BYVAL wzFileName AS WSTRINGZ * %MAX_PATH, OPTIONAL BYVAL wzPath AS WSTRINGZ * %MAX_PATH) AS LONG
                     LOCAL hFile          AS DWORD
                     LOCAL FileAttributes AS DWORD
                     LOCAL LastError      AS LONG
                     LOCAL RetVal         AS LONG
                     LOCAL CleanupError   AS LONG
                     LOCAL wzCleanUp      AS WSTRINGZ * %MAX_PATH
                    
                     'Space or dot ending filename
                     IF ASC(wzFileName, -1) = 32 OR ASC(wzFileName, -1) = 46 THEN
                       EXIT FUNCTION
                     END IF
                    
                     IF LEN(wzPath) THEN
                       'Add ending "\" to optionnal folder if needed
                       IF ASC(wzPath, -1) <> 92 THEN
                         wzPath &= "\"
                       END IF
                       'isFolder exist
                       IF GetFileAttributes(wzPath) AND &HFF000010??? <> %FILE_ATTRIBUTE_DIRECTORY THEN
                         EXIT FUNCTION
                       END IF
                     ELSE
                       'Get OS temporary path, aka C:\Users\Pierre\AppData\Local\Temp\
                       GetTempPathW(SIZEOF(wzPath) / 2, wzPath)
                     END IF
                    
                     'Clean up filename from invalid characterts
                     wzCleanUp = wzFileName 'Keep genuine intact
                     RetVal = PathCleanupSpec(wzPath, wzCleanUp) 'File system aware, PathCleanupSpec may be unavailable in the future.
                     IF RetVal THEN
                       EXIT FUNCTION
                     END IF
                     'IF INSTR(wzFileName, ANY "<>:""/\|?*" & CHR$$(0)) THEN 'Invalid char, job done by PathCleanupSpec above
                     '  EXIT FUNCTION
                     'END IF
                    
                     'Reserved filename
                     SELECT CASE LCASE$(wzFileName)
                       CASE "con", "prn", "aux", "nul", "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", _
                            "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9"
                         EXIT FUNCTION
                     END SELECT
                    
                     'Reserved filename.ext
                     RetVal = INSTR(wzFileName, ".")
                     IF RetVal THEN
                       SELECT CASE LEFT$(LCASE$(wzFileName), RetVal) 'Invalid Filename
                         CASE "con.", "prn.", "aux.", "nul.", "com1.", "com2.", "com3.", "com4.", "com5.", "com6.", "com7.", "com8.", "com9", _
                              "lpt1.", "lpt2.", "lpt3.", "lpt4.", "lpt5.", "lpt6.", "lpt7.", "lpt8.", "lpt9."
                           EXIT FUNCTION
                       END SELECT
                     END IF
                    
                     'Create a test file if it dosen't exist or open it if it exist
                     hFile = CreateFileW(wzPath & wzFileName, %GENERIC_READ OR %GENERIC_WRITE, _
                                         %FILE_SHARE_READ OR %FILE_SHARE_WRITE, BYVAL 0, _
                                         %OPEN_ALWAYS, %FILE_ATTRIBUTE_NORMAL, 0)
                     LastError = GetLastError()
                    
                     'Does file exist
                     FileAttributes = GetFileAttributes(wzPath & wzFileName) AND &HFF000010???
                    
                     'File exist
                     IF FileAttributes = %FALSE THEN
                       FUNCTION = %TRUE
                     END IF
                    
                     'File was opened
                     IF hFile <> %INVALID_HANDLE_VALUE THEN
                       CloseHandle(hFile)
                       IF LastError <> %ERROR_ALREADY_EXISTS THEN
                         'Delete newly created file
                         DeleteFile(wzPath & wzFileName)
                       END IF
                     END IF
                    
                    END FUNCTION
                    '_____________________________________________________________________________
                    
                    FUNCTION isValidFileNameShow(BYVAL wzFileName AS WSTRINGZ * %MAX_PATH, OPTIONAL BYVAL wzPath AS WSTRINGZ * %MAX_PATH)AS LONG
                     LOCAL isValid AS LONG
                    
                     isValid = isValidFileNameRW(wzFileName, wzPath)
                     MessageBox(%HWND_DESKTOP, wzPath & wzFileName & $CRLF & _
                                IIF$(isValid, "Valid file name", "Invalid file name"), _
                                "isValidFileNameShow", %MB_OK OR %MB_TOPMOST)
                     FUNCTION = isValid
                    
                    END FUNCTION
                    '_____________________________________________________________________________
                    
                    FUNCTION PBMAIN()
                     LOCAL isValid AS LONG
                    
                     isValid = isValidFileNameShow("Test.bas")
                     isValid = isValidFileNameShow("Test*.bas")
                     isValid = isValidFileNameShow("Test.bas" & CHR$$(10))
                     isValid = isValidFileNameShow("...")
                     isValid = isValidFileNameShow("COM9")
                     isValid = isValidFileNameShow("COM99")
                     isValid = isValidFileNameShow("COM1.txt")
                     isValid = isValidFileNameShow("TestX.bas", "X:\") 'Set an invalid drive
                     isValid = isValidFileNameShow("Test.basSpace ")
                     isValid = isValidFileNameShow("Test.basDot.")
                    
                    END FUNCTION
                    '_____________________________________________________________________________
                    '

                    Comment


                    • #11
                      Pierre!

                      Thanks for the effort on the code! I'm about to crash for the night (have a bad cold) and will look at it tomorrow.

                      Comment


                      • #12
                        Originally posted by Stuart McLachlan View Post

                        The API is OS specific but storage media are not, they are diverse. What is a valid filename when writing to a CD, to a Linux NAS device, to a digital camera or android device? How does Win32 know where you want to create the file?
                        Good point. I guess that depends on the usage scenario.

                        1) Implement a generic function that 'just' checks a file name without actually intending to use the result in the application.

                        2) Have a use case such as 'Save As...'. Then either Windows can access the file system and this API implies that it can create valid file names. If the file system is unknown to Windows, then it wouldn't even recognize the "media" it's supposed to write to.

                        That said, it seems like Delphi inculdes such a (generic) method from which one might be able to create a PB version: http://docwiki.embarcadero.com/Libra...idFileNameChar

                        Comment


                        • #13
                          I believe we can turn their list into a simple CHR$() statement?
                          Code:
                          Invalid Characters
                          
                          Windows
                             #0, #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #24, #25, #26, #27, #28, #29, #30, #31, '"', '*', '/', ':', '<', '>', '?', '\' and '|'.
                          
                          PB:   CHR$(0 TO 31, $DQ, "*/:<>?\|")
                          
                          
                          MacOS, iOS, Android, and Linux
                             #0, #1, #2, #3, #4, #5, #6, #7, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18, #19, #20, #21, #22, #23, #24, #25, #26, #27, #28, #29, #30, #31, '/' and '~'.
                          
                          PB:   CHR$(0 TO 31, "/~")
                          Now can test via PB's TALLY or VERIFY...

                          -John

                          Comment


                          • #14
                            Important note if backslash is in file name
                            The function (post #5), tested here, will fail if there is a \ in the file name because PathCleanupSpec considers backslash invalid.
                            https://docs.microsoft.com/en-us/win...athcleanupspec


                            Also PathCleanupSpec return value might throw off the return value thinking true was returned in the rare case?
                            If the full path—the number of characters in the path at pszDir plus the number of characters in the cleaned name at pszSpec—exceeds MAX_PATH – 1 (to account for the terminating null character), the function returns PCS_PATHTOOLONG.

                            Code:
                            #INCLUDE "win32api.inc"
                            
                            FUNCTION PBMAIN () AS LONG
                             LOCAL fName AS WSTRINGZ * %MAX_PATH
                             LOCAL result AS LONG
                             fName = EXE.PATH$ + "test"
                             result = IsValidFileNameString(fName)
                             ? STR$(result)  ' -1 success
                            END FUNCTION
                            
                            FUNCTION IsValidFileNameString(fName AS WSTRINGZ * %MAX_PATH) AS LONG
                             LOCAL temp AS WSTRINGZ * %MAX_PATH
                             temp = fName
                             PathCleanupSpec  EXE.PATH$, fName
                             FUNCTION = (temp=fName)
                            END FUNCTION
                            https://duckduckgo.com instead of google

                            Comment


                            • #15
                              And some quick questions to Gary:
                              Does the goal of the valid filename function is to write to media right after verification?
                              Does a function that check for a valid filename "could" or "have to" include also the full path?
                              Does the path, if used, have to already exist on media?
                              Does a function that check for a valid filename have to be file system aware or just fit on many known system?

                              A pretty good résumé of the traps by D.R.F.

                              Comment


                              • #16
                                Path or strictly just filename and extension?

                                A stray back slash in the name would make the part of the name to left look like a non-existent directory. Fails anyway.
                                Dale

                                Comment


                                • #17
                                  Pierre,
                                  Yes, my intended use is to write to media after verification. The string could include path information but the function can ignore the path and test only the filename/extension. The calling app should handle whether the intended path exists. I'm only interested in Win10, but covering Win7 is probably a good idea.

                                  Comment


                                  • #18
                                    Thanks everyone. Here is it 10 years after I started using PBWin and I'm always amazed that even basic tasks can still generate interest and new code. One more reason to love coding!

                                    My takeaways are that a generic solution is harder than might be expected, that any solution won't be a simple API call, and that a "try it to see if it fails" function such as I put in the OP is a reasonable way to go.

                                    Comment


                                    • #19
                                      Originally posted by Gary Beene View Post
                                      [B] ... and that a "try it to see if it fails" function such as I put in the OP is a reasonable way to go.
                                      No code to show but another thing to consider is a regular expression filter allowing only chars that you deem suitable: A-Z,a-z,0-9,and so on.
                                      We've all heard, garbage in, garbage out. Yet it's always preferable to seek a "garbage doesn''t get in" solution. That's my 2¢

                                      Comment


                                      • #20
                                        I am with Kevin all the way and I sure ain't for spaces in file names either.
                                        Y'all should see some of the most rediculious file names and huge length file names I have come across.
                                        If the files don't get into your backup plan or even breaks it. It will not be so funny.

                                        p purvis

                                        Comment

                                        Working...
                                        X