I've gone back to the script and improved it somewhat.
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)
}
;==================================================
@LogicDaemon: Thanks for your latest comment, interesting.