Kilmatead Posted June 2, 2014 Share Posted June 2, 2014 Yes, I know, one can hardly complain when an undocumented feature is "removed" from a function, but just out of my own curiosity (as it's script-changing), I'm wondering if it was intentional or just a random side-effect. Essentially (in pre-3.3.12.0) FileGetLongName was a convenient means of regularising the "case" of a given qualified path: FileGetLongName("c:program files") would return "C:Program Files", etc. Since NTFS is case-agnostic this had no impact on actual usage, but it was infinitely useful when users would type in a location, and you could clean up the (verified) text before displaying the path, especially when it came to relative-path transformations. Since 3.3.12.0. however, it does no case-correction at all, and seems to behave exactly the same as _WinAPI_GetFullPathName. Now, obviously this isn't the end of the world - a raggety-line of 5 nested functions can accomplish the behaviour I expect: FileGetLongName(FileGetShortName(StringUpper(StringLeft($sFile, 1)) & StringMid($sFile, 2))) ...but hey, 5:1 isn't really a bad ratio. (Yes, the extra string functions are needed as the drive letter itself remains lower-case, while the rest is auto-corrected - all in all it's still easier than dancing along the components rebuilding the path manually by reading each from the drive.) Anyway, is there now any benefit to using the inbuilt function over the API call, or is this just a quirk effecting only me? Link to comment Share on other sites More sharing options...
BrewManNH Posted June 2, 2014 Share Posted June 2, 2014 You could use _StringTitleCase to clean up the text if you wanted to use a single function. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
Kilmatead Posted June 2, 2014 Author Share Posted June 2, 2014 (edited) _StringTitleCase doesn't have any relation to the actual pathname on the disc itself - it's just a blind-formatter. I'm talking about retrieving the actual case contained within the filenames themselves. True, as I said above, it's a purely aesthetic thing (unless you play with FILE_FLAG_POSIX_SEMANTICS cross-platform nomenclature), but there's no end of workaround threads on stackoverflow related to it - so somebody besides me must pay attention to these things. I just always found it convenient that it was built-in to the native FGLN function - and now it's not. Edited June 2, 2014 by Kilmatead Link to comment Share on other sites More sharing options...
BrewManNH Posted June 2, 2014 Share Posted June 2, 2014 _StringTitleCase doesn't have any relation to the actual pathname on the disc itself - it's just a blind-formatter.Neither does this have any relation to the path name returned, I was merely making a counter suggestion to your 5 functions and just using one. FileGetLongName(FileGetShortName(StringUpper(StringLeft($sFile, 1)) & StringMid($sFile, 2))) If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
Kilmatead Posted June 2, 2014 Author Share Posted June 2, 2014 ...except in this case that "one" function doesn't actually do anything useful (it only capitalises an arbitrary string) - the 5-function example returns the existing case of whatever filesystem object you point it at, that's what I'm referring to. I could use _WinAPI_GetFinalPathNameByHandle, except that doesn't exist in XP and it also doesn't always return the given path (in the case of links). Like I said, the workaround isn't important (as long as it works), I'm just curious about the change in the original function - since it doesn't seem to be much different, otherwise. Link to comment Share on other sites More sharing options...
BrewManNH Posted June 2, 2014 Share Posted June 2, 2014 Here's a quick proof of concept script I threw together that will allow you to fix the issue until something official comes along. One function call, and no UDFs needed. $sFile = "c:\progra~1\" $sFile1 = "c:\pRoGraM fiLes" ConsoleWrite(FileGetLongName(FileGetShortName(StringUpper(StringLeft($sFile, 1)) & StringMid($sFile, 2))) & @CRLF) ConsoleWrite(FileGetLongName(FileGetShortName(StringUpper(StringLeft($sFile1, 1)) & StringMid($sFile1, 2))) & @CRLF) ConsoleWrite(FileGetLongName($sFile) & @CRLF) ; correct case returned ConsoleWrite(FileGetLongName($sFile1) & @CRLF) ; <<<<<<<<<< wrong case returned ConsoleWrite($sFile & ' => ' & _WinAPI_GetCaseCorrectLongFileName($sFile) & @CRLF) ; works with short path/file names ConsoleWrite($sFile1 & ' => ' & _WinAPI_GetCaseCorrectLongFileName($sFile1) & @CRLF) ; and long path/file names, even with the case wrong Func _WinAPI_GetCaseCorrectLongFileName($sFile) Local $Ret = DllCall('kernel32.dll', 'dword', 'GetLongPathNameW', 'wstr', $sFile, 'wstr', '', 'dword', 4096) $test = ObjCreate("Scripting.FileSystemObject") Return $test.GetAbsolutePathName($Ret[2]) EndFunc ;==>_WinAPI_GetLongPathName It SHOULD work with either folder names or file names If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
Kilmatead Posted June 2, 2014 Author Share Posted June 2, 2014 Now that's more interesting - though it does require the object to exist in the first place, else it returns the currently working directory (which is obviously impractical); adding a simple FileExists check before calling the GetLongPathNameW would do the trick in a blunt way, but doing a canonical call first will resolve as much of the path as possible (and return it) to provide the most clarity in case of failure: Func _WinAPI_GetCaseCorrectLongFileName($sFile) $sFile = _WinAPI_PathCanonicalize($sFile) If Not FileExists($sFile) Then Return $sFile Local $Ret = DllCall('kernel32.dll', 'dword', 'GetLongPathNameW', 'wstr', $sFile, 'wstr', '', 'dword', 4096) Local $oTarget = ObjCreate("Scripting.FileSystemObject") Return $oTarget.GetAbsolutePathName($Ret[2]) EndFunc ...thus "C:ExistingExisting....usersNonExisting" returns "c:usersNonExisting" which may not be case-wise sound (obviously, as it doesn't exist) but it certainly returns a close approximation to the requested object, and is safe to use on user-input. Which brings us down to 4 function-calls (without the canonical it'd be 3), allowing for relative paths and non-existing objects. Thanks for this - better than my first work-around, and even better than the "old" FileGetLongName which could not deduce relative paths, though at least returned the given path on failure. Link to comment Share on other sites More sharing options...
BrewManNH Posted June 2, 2014 Share Posted June 2, 2014 If the path doesn't exist, it should set the error condition and return the $sFile parameter. I see no reason to include _WinAPI_PathCanonicalize in the function unless you're not replacing the standard FileGetLongName function, because that function doesn't use it or anything like it. You could use the $oTarget.GetAbsolutePathName to replace the _WinAPI_PathCanonicalize function with your "C:ExistingExisting....usersNonExisting" path string to return the same result. BTW, none of the functions in the snippet return anything but the parameter and an error if the file or folder doesn't exist. Also forgot to mention, the above snippet I posted works back to WinXP. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
Kilmatead Posted June 2, 2014 Author Share Posted June 2, 2014 (edited) I tacked on the _WinAPI_PathCanonicalize because GetLongPathNameW automatically does the same thing (as does the FileExists call) - I didn't realise that the com's GetAbsolutePathName would do it too - all's the better. (In fact, a quick check shows that on error GetAbsolutePathName will properly case the part of the canonicalised pathname which does exist, and leave the rest [without truncation], which is perfect.) Technically none of this was necessary, as my original 5-function mess provided the precise same results (existing/nonexisting) as the old FileGetLongName, but yours reduces that by 1 at least (an extra SetError and FileExists on top of the other two). The standard FileGetLongName function was more or less irrelevant to me as I only ever used it to "clean" filepaths - at which it worked admirably, until someone decided to neuter it. So, if I have to replace it anyway, I'll take advantage of building in any extra things that serve a purpose, and canonicalised paths on error fits the bill. Func _WinAPI_GetCaseCorrectLongFileName($sFile) Local $oTarget = ObjCreate("Scripting.FileSystemObject") If FileExists($sFile) Then Local $Ret = DllCall('kernel32.dll', 'dword', 'GetLongPathNameW', 'wstr', $sFile, 'wstr', '', 'dword', 4096) Return $oTarget.GetAbsolutePathName($Ret[2]) EndIf Return SetError(1, 0, $oTarget.GetAbsolutePathName($sFile)) EndFunc Edited June 2, 2014 by Kilmatead Link to comment Share on other sites More sharing options...
Ascend4nt Posted June 5, 2014 Share Posted June 5, 2014 Brewmanh/Kilmataed, maybe you could submit this as a UDF for inclusion with AutoIt, or at least put it in the Example Scripts forum, as this will probably prove useful to others. I believe the old FileGetLongName() used a SHGetPathFromIDList() call somewhere.. My contributions: Performance Counters in Windows - Measure CPU, Disk, Network etc Performance | Network Interface Info, Statistics, and Traffic | CPU Multi-Processor Usage w/o Performance Counters | Disk and Device Read/Write Statistics | Atom Table Functions | Process, Thread, & DLL Functions UDFs | Process CPU Usage Trackers | PE File Overlay Extraction | A3X Script Extract | File + Process Imports/Exports Information | Windows Desktop Dimmer Shade | Spotlight + Focus GUI - Highlight and Dim for Eyestrain Relief | CrossHairs (FullScreen) | Rubber-Band Boxes using GUI's (_GUIBox) | GUI Fun! | IE Embedded Control Versioning (use IE9+ and HTML5 in a GUI) | Magnifier (Vista+) Functions UDF | _DLLStructDisplay (Debug!) | _EnumChildWindows (controls etc) | _FileFindEx | _ClipGetHTML | _ClipPutHTML + ClipPutHyperlink | _FileGetShortcutEx | _FilePropertiesDialog | I/O Port Functions | File(s) Drag & Drop | _RunWithReducedPrivileges | _ShellExecuteWithReducedPrivileges | _WinAPI_GetSystemInfo | dotNETGetVersions | Drive(s) Power Status | _WinGetDesktopHandle | _StringParseParameters | Screensaver, Sleep, Desktop Lock Disable | Full-Screen Crash Recovery Wrappers/Modifications of others' contributions: _DOSWildcardsToPCRegEx (original code: RobSaunder's) | WinGetAltTabWinList (original: Authenticity) UDF's added support/programming to: _ExplorerWinGetSelectedItems | MIDIEx UDF (original code: eynstyne) (All personal code/wrappers centrally located at Ascend4nt's AutoIT Code) Link to comment Share on other sites More sharing options...
guinness Posted June 5, 2014 Share Posted June 5, 2014 Examples section please. Also for compatibility use the _WinAPI_* function calls to reduce bloat in a user's script. Thanks. UDF List: _AdapterConnections() • _AlwaysRun() • _AppMon() • _AppMonEx() • _ArrayFilter/_ArrayReduce • _BinaryBin() • _CheckMsgBox() • _CmdLineRaw() • _ContextMenu() • _ConvertLHWebColor()/_ConvertSHWebColor() • _DesktopDimensions() • _DisplayPassword() • _DotNet_Load()/_DotNet_Unload() • _Fibonacci() • _FileCompare() • _FileCompareContents() • _FileNameByHandle() • _FilePrefix/SRE() • _FindInFile() • _GetBackgroundColor()/_SetBackgroundColor() • _GetConrolID() • _GetCtrlClass() • _GetDirectoryFormat() • _GetDriveMediaType() • _GetFilename()/_GetFilenameExt() • _GetHardwareID() • _GetIP() • _GetIP_Country() • _GetOSLanguage() • _GetSavedSource() • _GetStringSize() • _GetSystemPaths() • _GetURLImage() • _GIFImage() • _GoogleWeather() • _GUICtrlCreateGroup() • _GUICtrlListBox_CreateArray() • _GUICtrlListView_CreateArray() • _GUICtrlListView_SaveCSV() • _GUICtrlListView_SaveHTML() • _GUICtrlListView_SaveTxt() • _GUICtrlListView_SaveXML() • _GUICtrlMenu_Recent() • _GUICtrlMenu_SetItemImage() • _GUICtrlTreeView_CreateArray() • _GUIDisable() • _GUIImageList_SetIconFromHandle() • _GUIRegisterMsg() • _GUISetIcon() • _Icon_Clear()/_Icon_Set() • _IdleTime() • _InetGet() • _InetGetGUI() • _InetGetProgress() • _IPDetails() • _IsFileOlder() • _IsGUID() • _IsHex() • _IsPalindrome() • _IsRegKey() • _IsStringRegExp() • _IsSystemDrive() • _IsUPX() • _IsValidType() • _IsWebColor() • _Language() • _Log() • _MicrosoftInternetConnectivity() • _MSDNDataType() • _PathFull/GetRelative/Split() • _PathSplitEx() • _PrintFromArray() • _ProgressSetMarquee() • _ReDim() • _RockPaperScissors()/_RockPaperScissorsLizardSpock() • _ScrollingCredits • _SelfDelete() • _SelfRename() • _SelfUpdate() • _SendTo() • _ShellAll() • _ShellFile() • _ShellFolder() • _SingletonHWID() • _SingletonPID() • _Startup() • _StringCompact() • _StringIsValid() • _StringRegExpMetaCharacters() • _StringReplaceWholeWord() • _StringStripChars() • _Temperature() • _TrialPeriod() • _UKToUSDate()/_USToUKDate() • _WinAPI_Create_CTL_CODE() • _WinAPI_CreateGUID() • _WMIDateStringToDate()/_DateToWMIDateString() • Au3 script parsing • AutoIt Search • AutoIt3 Portable • AutoIt3WrapperToPragma • AutoItWinGetTitle()/AutoItWinSetTitle() • Coding • DirToHTML5 • FileInstallr • FileReadLastChars() • GeoIP database • GUI - Only Close Button • GUI Examples • GUICtrlDeleteImage() • GUICtrlGetBkColor() • GUICtrlGetStyle() • GUIEvents • GUIGetBkColor() • Int_Parse() & Int_TryParse() • IsISBN() • LockFile() • Mapping CtrlIDs • OOP in AutoIt • ParseHeadersToSciTE() • PasswordValid • PasteBin • Posts Per Day • PreExpand • Protect Globals • Queue() • Resource Update • ResourcesEx • SciTE Jump • Settings INI • SHELLHOOK • Shunting-Yard • Signature Creator • Stack() • Stopwatch() • StringAddLF()/StringStripLF() • StringEOLToCRLF() • VSCROLL • WM_COPYDATA • More Examples... Updated: 22/04/2018 Link to comment Share on other sites More sharing options...
Kilmatead Posted June 5, 2014 Author Share Posted June 5, 2014 (edited) ...for compatibility use the _WinAPI_* function calls to reduce bloat in a user's script. Interestingly enough, there is no _WinAPI_ for GetLongPathNameW defined in the AI library (probably because the native function exists). Technically that call is superfluous here anyway, as the (otherwise banjaxed) FileGetLongName will serve the same purpose: Func _GetCaseCorrectLongFileName($sFile) If FileExists($sFile) Then Local $oTarget = ObjCreate("Scripting.FileSystemObject") Return $oTarget.GetAbsolutePathName(FileGetLongName($sFile)) Else Return SetError(1, 0, $sFile) EndIf EndFunc (This thread was not meant to be about a new function, it was just asking why something else went mysteriously "poof"...) Edited June 5, 2014 by Kilmatead Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now