Hi all.
I need to work with long paths, and I hoped AutoHotkey is appropriate tool for almost anything. Unfortunately, Loop operator betrayed me, since it intentionally ignores files with paths longer than 259 char, even if I prefix the path with \\?\
Seriously, most programs nowadays don't stick to that limit and work well with long paths! (not the explorer, though it shows them and appropriately passes as arguments to other programs)
Can we please lift that artificial limit? Maybe with some #LongFilenames or when \\?\ prefix is explicitly used.
And meanwhile, can anyone feed me workaround for Loop, Files please? Maybe using dllcall FindFirstFile, FindNextFile, and FindClose (without practice, it's time consuming to figure out how to correctly prepare memory and put arguments for DllCall).
Otherwise, I'll rely on %comspec% /C DIR /B, which is very crutchy.
259-char path limit workarounds Topic is solved
-
- Posts: 21
- Joined: 21 Feb 2014, 01:22
259-char path limit workarounds
Last edited by LogicDaemon on 27 Dec 2016, 12:41, edited 3 times in total.
Re: 259-char path limit workarounds
I wrote a script for this I'll try and post it in a moment. For dealing with long filenames if you somehow acquire the short-form path, you can use that in AutoHotkey.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: 259-char path limit workarounds
Apologies, the script isn't up to my usual standards, I was planning to perfect it in the next few months.
I'm not really an expert programmer, so it really takes it out of me every time I do something like this.
I think it would be great if AutoHotkey could add long filename support, and alphabetical order registry loop.
I have had to create some fiendish complicated functions for Sort command to correctly alphabetise registry entries after a loop.
Checking for long filenames was one of the first things I hoped to do with AutoHotkey.
EDIT: It may be that this script does not currently retrieve files from within folders with long paths.
I'm not really an expert programmer, so it really takes it out of me every time I do something like this.
I think it would be great if AutoHotkey could add long filename support, and alphabetical order registry loop.
I have had to create some fiendish complicated functions for Sort command to correctly alphabetise registry entries after a loop.
Checking for long filenames was one of the first things I hoped to do with AutoHotkey.
EDIT: It may be that this script does not currently retrieve files from within folders with long paths.
Code: Select all
;z list all files (file loop + custom file loop) (FindFirstFile).ahk
;note: it may be that this script does not currently retrieve files from within folders with long paths
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
;note: doesn't get files from root of c
if A_Is64bitOS
DllCall("Wow64DisableWow64FsRedirection", "uint*", OldValue)
vOutput3 := ""
VarSetCapacity(vOutput3, 10000000*2)
vOutput4 := ""
VarSetCapacity(vOutput4, 10000000*2)
vOutput5 := ""
VarSetCapacity(vOutput5, 10000000*2)
vIndex := 0
Loop, C:\*.*, 2, 1 ;(0/1/2=files/both/folders, 0/1=subfolders no/subfolders yes)
{
vDirX := A_LoopFileFullPath
;vDirX = %A_ScriptDir%
;==================================================
;FILE LOOP
vOutput := ""
Loop, %vDirX%\*.*, 1, 0 ;(0/1/2=files/both/folders, 0/1=subfolders no/subfolders yes)
{
vPath := A_LoopFileFullPath
vName := A_LoopFileName ;filename (minus path)
vAttrib := DllCall("GetFileAttributes", "str", vPath)
;vOutput .= vAttrib "`t" vName "`r`n"
vOutput .= vAttrib "`t" vPath "`r`n"
}
;===============
;FILE LOOP CUSTOM
vDirX2 = \\?\%vDirX%\*
VarSetCapacity(filedata, 2000,0)
hFile := DllCall("Kernel32.dll\FindFirstFile", "str", vDirX2, "ptr", &filedata)
vOutput2 := ""
;=====
if !(hFile = -1)
{
vAttrib := NumGet(&filedata)
vName := strget(&filedata+44)
vPath = %vDirX%\%vName%
if vName not in .,..
;vOutput2 .= vAttrib "`t" vName "`r`n"
vOutput2 .= vAttrib "`t" vPath "`r`n"
while DllCall("Kernel32.dll\FindNextFile", "ptr", hFile, "ptr", &filedata)
{
vAttrib := NumGet(&filedata)
vName := strget(&filedata+44)
vPath = %vDirX%\%vName%
if vName not in .,..
;vOutput2 .= vAttrib "`t" vName "`r`n"
vOutput2 .= vAttrib "`t" vPath "`r`n"
}
DllCall("Kernel32.dll\FindClose", "ptr", hFile)
}
;=====
;===============
if 0
if (vOutput = vOutput2)
Sleep 0 ;MsgBox y (%vDirX%)
else
{
Clipboard := "[METHOD 1] " vDirX "`r`n" vOutput "[METHOD 2] " vDirX "`r`n" vOutput2 "`r`n"
MsgBox n (%vDirX%)
}
;Clipboard := vOutput "`r`n`r`n" vOutput2
;MsgBox done
if !(vOutput = vOutput2)
{
vIndex := vIndex+1
vOutput3 .= "[METHOD 1] " vDirX "`r`n" vOutput "[METHOD 2] " vDirX "`r`n" vOutput2 "`r`n"
vOutput4 .= "[METHOD 1] " vDirX "`r`n" vOutput "`r`n"
vOutput5 .= "[METHOD 2] " vDirX "`r`n" vOutput2 "`r`n"
}
;==================================================
}
vDate := A_Now
vPath3 = %A_Desktop%\z compare folders %vDate%.txt
vPath4 = %A_Desktop%\z compare folders %vDate% 1.txt
vPath5 = %A_Desktop%\z compare folders %vDate% 2.txt
FileAppend, %vOutput3%, *%vPath3%, UTF-8
FileAppend, %vOutput4%, *%vPath4%, UTF-8
FileAppend, %vOutput5%, *%vPath5%, UTF-8
MsgBox done
Return
Last edited by jeeswg on 31 Jan 2017, 05:08, edited 3 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: 259-char path limit workarounds
OK it appears shift+right click, Copy Path, on a long filename, returns blank.
And Edit, Copy, and retrieve %Clipboard%, returns blank.
Anyhow, in the FindFirstFile filename loop above you can retrieve
the short paths as well as the full paths.
EDIT: it may be that this script does not currently retrieve files from within folders with long paths.
And Edit, Copy, and retrieve %Clipboard%, returns blank.
Anyhow, in the FindFirstFile filename loop above you can retrieve
the short paths as well as the full paths.
EDIT: it may be that this script does not currently retrieve files from within folders with long paths.
Last edited by jeeswg on 27 Dec 2016, 14:22, edited 1 time in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 21
- Joined: 21 Feb 2014, 01:22
Re: 259-char path limit workarounds
Windows 10 release has same problem for me, but on "slow" Insider Preview (build 14986), it returns double-quoted \\?\-prefixed path.OK it appears shift+right click, Copy Path, on a long filename, returns blank.
But I use Total Commander most of the time anyway.
Works for me on both Windows 10 machines (release and Insider Preview)And Edit, Copy, and retrieve %Clipboard%, returns blank.
Thanks for the script anyhow!
Re: 259-char path limit workarounds Topic is solved
OK, turns out I did do the full folder loop too, yes, that was properly fiendish, especially as I have to make up programming paradigms as I go along, for not knowing them, for dealing with the hierarchies in memory.
I can't vouch 100% for the accuracy of this script, and it was due to be checked over also in the next few months.
I can't vouch 100% for the accuracy of this script, and it was due to be checked over also in the next few months.
Code: Select all
;z list files 1 jee.ahk
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
SplitPath, A_ScriptName,,,, vScriptNameNoExt
Menu, Tray, Tip, % vScriptNameNoExt
;==================================================
#MaxMem 500
if A_Is64bitOS
DllCall("kernel32.dll\Wow64DisableWow64FsRedirection", "UInt*", 0)
;01:02 22/04/2016
;q:: ;test - list all files + folders (custom file loop) (recurse)
vSearchDir := A_Desktop "\new fol\! txt\test list files 1"
vSearchDir := A_Desktop
vSearchDir := "C:\"
vSearchDir := A_Desktop "\new fol"
MsgBox, % vSearchDir
vSearchDir := RTrim(vSearchDir, "\")
vOutput := ""
VarSetCapacity(vOutput, 200*1000000*2)
VarSetCapacity(vFINDDATA, 2000, 0)
vLevelLast := 0
vLevelCurrent := 1
vLevelDir1 := vSearchDir
Loop
{
vSearchDir := vLevelDir%vLevelCurrent%
vSearchDir2 := "\\?\" vSearchDir "\*"
;if (A_Index = 5)
; break
;has this folder been seen before? (if last level < current level then no)
if (vLevelLast < vLevelCurrent)
{
vLevelSub%vLevelCurrent% := ""
;===============
Loop
{
if (A_Index = 1)
{
hFile := DllCall("kernel32.dll\FindFirstFile", "Str", vSearchDir2, "Ptr", &vFINDDATA, "Ptr")
if (hFile = -1)
break
}
if (A_Index > 1)
if !DllCall("kernel32.dll\FindNextFile", "Ptr", hFile, "Ptr", &vFINDDATA)
{
DllCall("kernel32.dll\FindClose", "Ptr", hFile)
break
}
vAttrib := NumGet(&vFINDDATA, 0, "UInt")
vName := StrGet(&vFINDDATA+44)
vPath := vSearchDir "\" vName
if vName not in .,..
if (StrLen(vPath) <= 259) ;to make it the same as AutoHotkey
vOutput .= vPath "`r`n"
;vOutput .= vAttrib "`t" vPath "`r`n"
if (vAttrib & 0x10) ;FILE_ATTRIBUTE_DIRECTORY := 0x10
if vName not in .,..
vLevelSub%vLevelCurrent% .= vName "|"
}
;===============
vLevelPoint%vLevelCurrent% := 1
vLevelLen%vLevelCurrent% := StrLen(vLevelSub%vLevelCurrent%)
}
;does this folder have unseen subfolders? (is pointer position greater than length of subfolders list)
if (vLevelPoint%vLevelCurrent% > vLevelLen%vLevelCurrent%)
{
if (vLevelCurrent = 1)
break
else
vLevelLast := vLevelCurrent, vLevelCurrent -= 1
}
else
{
;remove first unseen subfolder from list (move pointer for current level onwards), go to first unseen subfolder (set last level = current level, and increase 'current level')
vPos := InStr(vLevelSub%vLevelCurrent%, "|", 0, vLevelPoint%vLevelCurrent%)
vNameNext := SubStr(vLevelSub%vLevelCurrent%, vLevelPoint%vLevelCurrent%, (vPos-1)-vLevelPoint%vLevelCurrent%+1)
vLevelPoint%vLevelCurrent% := vPos+1
vDirNext := vLevelDir%vLevelCurrent% "\" vNameNext
vLevelLast := vLevelCurrent, vLevelCurrent += 1
vLevelDir%vLevelCurrent% := vDirNext
}
}
;Clipboard := vOutput
vPath := A_Desktop "\z list files " A_Now " jee.txt"
FileAppend, % vOutput, % "*" vPath, UTF-8
MsgBox, % "done"
return
;==================================================
Last edited by jeeswg on 04 Oct 2018, 16:55, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 21
- Joined: 21 Feb 2014, 01:22
Re: 259-char path limit workarounds
I know that's old topic, still I want to share what I've asked it for
In file zpaq.ahk, look the function "LongPathsInDir". It can be easily adopted to return directory contents (with subdirectories).
I've tweaked _WIN32_FIND_DATA struct size to be exact (not to waste any memory), and added comments for parsing of the attributes.
Why I needed it:
There is archiver called zpaq. Its command line is not that Intricate as 7-zip's one, and also there are weird caveats. For example, when adding to an archive without specifying \\?\ prefix for source paths (including cases when adding relative path), any files with full path length > 259 chars won't be added to the archive, they'll be skipped with a warning. Also, there is no way of feeding it a separate file list, all paths must be given on command line.
But I'm using total commander with usercmd.ini for dealing with zpaq archives, which only supports long paths in unicode file lists, and not on command line.
This is what zpaq.ahk saves from. First, it reads file lists and puts them right on command line for zpaq; second, it checks if there are any long paths,
and if there are, expands them to full paths with \\?\ prefix (otherwise, I get a warning in separate console window which closes once archiving is done, which is often split-second for whole operation if no files get added because they all had long paths).
In file zpaq.ahk, look the function "LongPathsInDir". It can be easily adopted to return directory contents (with subdirectories).
I've tweaked _WIN32_FIND_DATA struct size to be exact (not to waste any memory), and added comments for parsing of the attributes.
Why I needed it:
There is archiver called zpaq. Its command line is not that Intricate as 7-zip's one, and also there are weird caveats. For example, when adding to an archive without specifying \\?\ prefix for source paths (including cases when adding relative path), any files with full path length > 259 chars won't be added to the archive, they'll be skipped with a warning. Also, there is no way of feeding it a separate file list, all paths must be given on command line.
But I'm using total commander with usercmd.ini for dealing with zpaq archives, which only supports long paths in unicode file lists, and not on command line.
This is what zpaq.ahk saves from. First, it reads file lists and puts them right on command line for zpaq; second, it checks if there are any long paths,
and if there are, expands them to full paths with \\?\ prefix (otherwise, I get a warning in separate console window which closes once archiving is done, which is often split-second for whole operation if no files get added because they all had long paths).
Re: 259-char path limit workarounds
I've gone back to the script and improved it somewhat.
@LogicDaemon: Thanks for your latest comment, interesting.
Code: Select all
#SingleInstance force
ListLines, Off
#KeyHistory 0
Menu, Tray, Click, 1
#NoEnv
AutoTrim, Off
#UseHook
SplitPath, A_ScriptName,,,, vScriptNameNoExt
Menu, Tray, Tip, % vScriptNameNoExt
;==================================================
#MaxMem 600
if A_Is64bitOS
DllCall("kernel32\Wow64DisableWow64FsRedirection", PtrP,0)
;q:: ;list all files + folders (custom file loop) (recurse)
vSearchDir := "C:\"
vSearchDir := A_Desktop "\MyDir"
vOutput := ""
VarSetCapacity(vOutput, 260*1000000*2)
VarSetCapacity(WIN32_FIND_DATA, 592, 0)
vSearchDir := RTrim(vSearchDir, "\")
vLevelLast := 0
vLevelCurrent := 1
vLevelDir1 := vSearchDir
MAX_PATH := 260
;vInfo := "vAttrib"
;vInfo := "vDateC"
;vInfo := "vDateA"
;vInfo := "vDateM"
;vInfo := "vSize"
;vInfo := "vNameShort"
vInfo := "vLen"
;==================================================
vOutput2 := ""
VarSetCapacity(vOutput2, 260*1000000*2)
Loop, Files, % vSearchDir "\*", FDR
{
vPath := A_LoopFileFullPath
vAttrib := A_LoopFileAttrib
vDateC := A_LoopFileTimeCreated
vDateA := A_LoopFileTimeAccessed
vDateM := A_LoopFileTimeModified
vSize := A_LoopFileSize
vNameShort := A_LoopFileShortName
vLen := StrLen(vPath)
vOutput2 .= %vInfo% "`t" vPath "`r`n"
}
Clipboard := vOutput2
;MsgBox, % "done (AHK File loop)"
;==================================================
Loop
{
vSearchDir := vLevelDir%vLevelCurrent%
vSearchDir2 := "\\?\" vSearchDir "\*"
;has this folder been seen before? (if last level < current level then no)
if (vLevelLast < vLevelCurrent)
{
vLevelSub%vLevelCurrent% := ""
;===============
Loop
{
if (A_Index = 1)
&& ((hFile := DllCall("kernel32\FindFirstFile", Str,vSearchDir2, Ptr,&WIN32_FIND_DATA)) = -1)
break
if (A_Index > 1)
&& !DllCall("kernel32\FindNextFile", Ptr,hFile, Ptr,&WIN32_FIND_DATA)
{
DllCall("kernel32\FindClose", Ptr,hFile)
break
}
vAttribNum := NumGet(&WIN32_FIND_DATA, 0, "UInt") ;dwFileAttributes
vAttrib := JEE_AhkNumToAttrib(vAttribNum)
vDateC := JEE_DateFileTimeToDate(&WIN32_FIND_DATA+4) ;ftCreationTime
vDateA := JEE_DateFileTimeToDate(&WIN32_FIND_DATA+12) ;ftLastAccessTime
vDateM := JEE_DateFileTimeToDate(&WIN32_FIND_DATA+20) ;ftLastWriteTime
vSize := NumGet(&WIN32_FIND_DATA, 32, "UInt") ;nFileSizeLow
vName := StrGet(&WIN32_FIND_DATA+44, MAX_PATH) ;cFileName[MAX_PATH]
vName := StrGet(&WIN32_FIND_DATA+44) ;cFileName[MAX_PATH]
vNameShort := StrGet(&WIN32_FIND_DATA+564, 14) ;cAlternateFileName[14]
if (vNameShort = "")
vNameShort := vName
vPath := vSearchDir "\" vName
vLen := StrLen(vPath)
if !(vName = ".") && !(vName = "..")
;&& (StrLen(vPath) <= 259) ;to make it the same as AutoHotkey (ignore long filenames)
;&& (StrLen(vPath) > 259) ;to only list long filenames
;vOutput .= vPath "`r`n"
vOutput .= %vInfo% "`t" vPath "`r`n"
if (vAttribNum & 0x10) ;FILE_ATTRIBUTE_DIRECTORY := 0x10
&& !(vName = ".") && !(vName = "..")
vLevelSub%vLevelCurrent% .= vName "|"
}
;===============
vLevelPoint%vLevelCurrent% := 1
vLevelLen%vLevelCurrent% := StrLen(vLevelSub%vLevelCurrent%)
}
;does this folder have unseen subfolders? (is pointer position greater than length of subfolders list)
if (vLevelPoint%vLevelCurrent% > vLevelLen%vLevelCurrent%)
{
if (vLevelCurrent = 1)
break
else
vLevelLast := vLevelCurrent, vLevelCurrent -= 1
}
else
{
;remove first unseen subfolder from list (move pointer for current level onwards), go to first unseen subfolder (set last level = current level, and increase 'current level')
vPos := InStr(vLevelSub%vLevelCurrent%, "|", 0, vLevelPoint%vLevelCurrent%)
vNameNext := SubStr(vLevelSub%vLevelCurrent%, vLevelPoint%vLevelCurrent%, (vPos-1)-vLevelPoint%vLevelCurrent%+1)
vLevelPoint%vLevelCurrent% := vPos+1
vDirNext := vLevelDir%vLevelCurrent% "\" vNameNext
vLevelLast := vLevelCurrent, vLevelCurrent += 1
vLevelDir%vLevelCurrent% := vDirNext
}
}
;Clipboard := vOutput
vPath := A_Desktop "\z list files " A_Now " jee.txt"
FileAppend, % vOutput, % "*" vPath, UTF-8
MsgBox, % "done"
;JEE_WinMergeCompareStrings("CUSTOM`r`n" vOutput, "AHK`r`n" vOutput2)
return
;==================================================
;note: this converts a number from GetFileAttributes or WIN32_FIND_DATA (dwFileAttributes) to match AutoHotkey's FileGetAttrib command
;note: this assumes the file exists
JEE_AhkNumToAttrib(vNum)
{
static oArray := {"R":0x1,"H":0x2,"S":0x4,"D":0x10,"A":0x20,"N":0x80,"T":0x100,"O":0x800,"E":0x1000,"C":0x4000,"V":0x10000}
static vList := "RASHNDOCT" ;RASHNDOCTEV
local vAttrib
Loop, Parse, vList
if (vNum & oArray[A_LoopField])
vAttrib .= A_LoopField
return (vAttrib = "") ? "X" : vAttrib
}
;==================================================
JEE_DateFileTimeToDate(vAddr, vLocal:=1, vLen:=14)
{
local vIntervals, vIntervals2, vDate
vIntervals := NumGet(vAddr+0, 0, "UInt64")
if vLocal
{
DllCall("kernel32\FileTimeToLocalFileTime", Int64P,vIntervals, Int64P,vIntervals2)
vIntervals := vIntervals2
}
vDate := 1601
vDate += vIntervals//10000000, S
if (vLen > 14)
vDate .= Format("{:03}", Mod(vIntervals//10000,1000)) ;milliseconds
return SubStr(vDate, 1, vLen)
}
;==================================================
Last edited by jeeswg on 17 Feb 2019, 17:26, edited 2 times in total.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: 259-char path limit workarounds
Here's another approach using objects:
Code: Select all
q:: ;list files in folder
vDir1 := A_ScriptDir
oShell := ComObjCreate("Shell.Application")
vCount := oShell.Namespace(vDir1).Items.Count
VarSetCapacity(vOutput, vCount*261 << !!A_IsUnicode)
for oItem in oShell.Namespace(vDir1).Items
;if !oItem.IsFolder
vOutput .= oItem.Path "`r`n"
oShell := oItem := ""
Clipboard := vOutput
MsgBox, % "done"
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
-
- Posts: 21
- Joined: 21 Feb 2014, 01:22
Re: 259-char path limit workarounds
Thanks I would certainly prefer DllCall over COM because of performance. COM is really, really slow, it's noticeable with large directories. And AutoHotkey is fairly fast if used properly, I'd say it's on par with php and maybe even python; much faster than batch files and wscript at least.
P.S. Just noticed there's "mark correct answer" button Pressed it on the response which helped me with my script
P.S. Just noticed there's "mark correct answer" button Pressed it on the response which helped me with my script
Re: 259-char path limit workarounds
I found that oItem.Path sometimes didn't work, it returned blanks, however, oItem.Name did appear to work consistently, although it matches what you see in the folder window, so extensions might be omitted.
Links:
Shell object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Shell.NameSpace method (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Folder object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
FolderItems object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
FolderItem object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Links:
Shell object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Shell.NameSpace method (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
Folder object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
FolderItems object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
FolderItem object (Windows)
https://msdn.microsoft.com/en-us/librar ... s.85).aspx
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: 259-char path limit workarounds
Here's an attempt at listing the selected files in an Explorer window (including long paths), using objects.
Code: Select all
q:: ;list selected files (attempts to handle long paths)
WinGet, hWnd, ID, A
oWin := ""
for oWin2 in ComObjCreate("Shell.Application").Windows
if (oWin2.HWND = hWnd)
{
oWin := oWin2
break
}
oWin2 := ""
if !oWin
return
vDir := oWin.Document.Folder.Self.Path
vOutput := ""
for oItem in oWin.Document.SelectedItems
{
;if !oItem.IsFolder
; continue
vPath := oItem.Path ;sometimes fails
if (vPath = "")
vPfx := "[Dir+Name/NameNoExt] ", vPath := vDir "\" oItem.Name ;can omit extension
else
vPfx := ""
if FileExist("\\?\" vPath)
{
vSize := DllCall("kernel32\GetLongPathName", Str,"\\?\" vPath, Ptr,0, UInt,0, UInt)
VarSetCapacity(vPath2, vSize*2, 0)
if DllCall("kernel32\GetLongPathName", Str,"\\?\" vPath, Str,vPath2, UInt,vSize, UInt)
vPath := (SubStr(vPath2, 1, 4) = "\\?\") ? SubStr(vPath2, 5) : vPath2
}
vOutput .= vPfx vPath "`r`n"
}
oWin := oItem := ""
Clipboard := vOutput
MsgBox, % vOutput
return
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
Re: 259-char path limit workarounds
Thank you so much. This was a job I needed.jeeswg wrote: ↑24 Nov 2017, 23:17Here's another approach using objects:Code: Select all
q:: ;list files in folder vDir1 := A_ScriptDir oShell := ComObjCreate("Shell.Application") vCount := oShell.Namespace(vDir1).Items.Count VarSetCapacity(vOutput, vCount*261 << !!A_IsUnicode) for oItem in oShell.Namespace(vDir1).Items ;if !oItem.IsFolder vOutput .= oItem.Path "`r`n" oShell := oItem := "" Clipboard := vOutput MsgBox, % "done" return
How can it be run for only one file?
Re: 259-char path limit workarounds
Is there a way to shorten the path to a local network file like this?
Code: Select all
LocalNetworkPath := "\\hlkli1\ISTKHKAKSKD\AADge Est MRTSKLDKMD\AbdtftKA_HLPKMSKYLKL\MRSTKTKSK KSKSKS\ABCKDKTKTKRTKT\HASANTRDocuments\New Folder\New Document.txt"
Who is online
Users browsing this forum: Rohwedder and 139 guests