;----------------------------------------------------------------------------------------------------------------------------------------- #DefineFunction udfPathMakeValid (strPath, strReplaceChar) ; Version 2.1. If strPath == "" Then Return "" strReplaceChar = StrSub (strReplaceChar, 1, 1) strValid = "" hdlShlwapi = DllLoad ("SHLWAPI.DLL") hdlBB = BinaryAlloc (260) ; MAX_PATH = 260 BinaryPokeStr (hdlBB, 0, strPath) intOffset = Max (0, DllCall (hdlShlwapi, long : "PathSkipRootA", lpbinary : hdlbb) - IntControl (42, hdlbb, 0, 0, 0)) ; CurrentOffset = MemBufferOffset - MemBufferStartAddress. strFp = BinaryPeekStr (hdlbb, intOffset, BinaryEodGet (hdlBB)) ; StrPos=CurrentOffset, StrLen=until end of string. strRt = BinaryPeekStr (hdlbb, 0, intOffset) ; StrPos=0=BufferStart, StrLen=CurrentOffset. blnHasRoot = strRt != "" If blnHasRoot intLen = StrLen (strRt) For intI = 1 To intLen strChar = StrSub (strRt, intI, 1) intResult = DllCall (hdlShlwapi, long : "PathGetCharTypeA", word : Char2Num (strChar)) Switch @TRUE Case intResult == 0 ; GCT_INVALID 0x0000 Case (intResult & 4) == 4; GCT_WILD 0x0004 strChar = strReplaceChar EndSwitch strValid = strValid : strChar Next EndIf If !blnHasRoot Then blnHasRoot = StrSub (strFp, 1, 1) == "\" ; Handle false positive. intLen = StrLen (strFp) For intI = 1 To intLen strChar = StrSub (strFp, intI, 1) intResult = DllCall (hdlShlwapi, long : "PathGetCharTypeA", word : Char2Num (strChar)) Switch @TRUE Case intResult == 0 ; GCT_INVALID 0x0000 Case (intResult & 4) == 4 ; GCT_WILD 0x0004 strChar = strReplaceChar Break Case strChar == ":" If blnHasRoot strChar = strReplaceChar Else blnHasRoot = @TRUE EndIf Break Case strChar == "\" If StrSub (strFp, intI - 1, 1) == "\" Then strChar = "" ; No replace, just remove backslash. EndSwitch strValid = strValid : strChar Next ; Remove trailing spaces per foldername. Note: Leading spaces are allowed by disksystem. While StrIndex (strValid, " \", 1, @FWDSCAN) strValid = StrReplace (strValid, " \", "\") EndWhile ; Remove overall leading and trailing spaces. strValid = StrTrim (strValid) BinaryEodSet (hdlBB, 0) BinaryPokeStr (hdlBB, 0, strPath) intResult = DllCall (hdlShlwapi, long : "PathCanonicalizeA", lpbinary : hdlBB, lpstr : strValid) If intResult Then strValid = BinaryPeekStr (hdlbb, 0, BinaryEodGet (hdlBB)) ; StrPos=0=BufferStart, StrLen=until end of string. hdlBB = BinaryFree (hdlBB) hdlShlwapi = DllFree (hdlShlwapi) Return strValid ;...................................................................................................................... ; Detlev Dalitz.20090705.20090707. ;...................................................................................................................... #EndFunction ;----------------------------------------------------------------------------------------------------------------------------------------- ; Test. DirChange (DirScript ()) ClipPut ("") strFilePath1 = "K:\;\F1\F2\File.ext" ; Valid. strFilePath2 = "D:;\FOL*DER;\<FOLDER>\\\..\;A:?/*.TXT" ; Invalid. strFilePath3 = '\/:.,;*?"<>|aA~' : Num2Char (127) : Num2Char (128) : Num2Char (26) : @CRLF ; Invalid. strFilePath4 = " aaa \ bbb \ ccc " ; Invalid. strReplaceChar = "_" strResult1 = udfPathMakeValid (strFilePath1, strReplaceChar) ; "K:\;\F1\F2\File.ext" ClipAppend (strResult1 : @LF) strResult2 = udfPathMakeValid (strFilePath2, strReplaceChar) ; "D:;\FOLDER;\;A.TXT" ; "D:;\FOL_DER;\;A____.TXT" ClipAppend (strResult2 : @LF) strResult3 = udfPathMakeValid (strFilePath3, strReplaceChar) ; "\.,;aA~" ; "\__.,;______aA~___" ClipAppend (strResult3 : @LF) strResult4 = udfPathMakeValid (strFilePath4, strReplaceChar) ; "aaa\ bbb\ ccc" ClipAppend (strResult4 : @LF) ;1 ;Try to create file. If DiskExist (strResult1) blnResult = DirMake (FilePath (strResult1)) If blnResult If FilePut (strResult1, "123") > 0 intPID = RunShell ("explorer.exe", '/e,/select,"' : FileFullname (strResult1) : '"', "", @ZOOMED, @GETPROCID) Display (10, "Note", "10 seconds to wait" : @LF : "or" : @LF : "Press Enter to continue.") blnResult = FileDelete (strResult1) strResult1 = FilePath (strResult1) strResult1 = ItemRemove (-(ItemExtract (-1, strResult1, "\") == ""), strResult1, "\") ; Remove trailing Backslash. While DirExist (strResult1) blnResult = DirRemove (strResult1) strResult1 = ItemRemove (-1, strResult1, "\") EndWhile TimeDelay (3) blnResult = WinClose (FindWindow ("ExploreWClass")) EndIf EndIf EndIf ;2 ;Try to create file. If DiskExist (strResult2) blnResult = DirMake (FilePath (strResult2)) If blnResult If FilePut (strResult2, "123") > 0 intPID = RunShell ("explorer.exe", '/e,/select,"' : FileFullname (strResult2) : '"', "", @ZOOMED, @GETPROCID) Display (10, "Note", "10 seconds to wait" : @LF : "or" : @LF : "Press Enter to continue.") blnResult = FileDelete (strResult2) strResult2 = FilePath (strResult2) strResult2 = ItemRemove (-(ItemExtract (-1, strResult2, "\") == ""), strResult2, "\") ; Remove trailing Backslash. While DirExist (strResult2) blnResult = DirRemove (strResult2) strResult2 = ItemRemove (-1, strResult2, "\") EndWhile TimeDelay (3) blnResult = WinClose (FindWindow ("ExploreWClass")) EndIf EndIf EndIf ;3 ; Try to create folder. blnResult = DirMake (strResult3) If blnResult intPID = RunShell ("explorer.exe", '/e,"' : strResult3 : '"', "", @ZOOMED, @GETPROCID) Display (10, "Note", "10 seconds to wait" : @LF : "or" : @LF : "Press Enter to continue.") blnResult = DirRemove (strResult3) TimeDelay (2) blnResult = WinClose (FindWindow ("ExploreWClass")) EndIf ;4 ;Try to create file. blnResult = DirMake (FilePath (strResult4)) If blnResult If FilePut (strResult4, "123") > 0 intPID = RunShell ("explorer.exe", '/e,/select,"' : FileFullname (strResult4) : '"', "", @ZOOMED, @GETPROCID) Display (10, "Note", "10 seconds to wait" : @LF : "or" : @LF : "Press Enter to continue.") blnResult = FileDelete (strResult4) strResult4 = FilePath (strResult4) strResult4 = ItemRemove (-(ItemExtract (-1, strResult4, "\") == ""), strResult4, "\") ; Remove trailing Backslash. While DirExist (strResult4) blnResult = DirRemove (strResult4) strResult4 = ItemRemove (-1, strResult4, "\") EndWhile TimeDelay (3) blnResult = WinClose (FindWindow ("ExploreWClass")) EndIf EndIf Exit