Page 1 of 1
Detect empty Start Menu folders?
Posted: Thu Jan 31, 2008 10:38 pm
by eJan
Hi, i need help here for my cleanup program: after deinstalling some programs in Start Menu remains empty folders. How to list and delete them?
DirectoryEntrySize(#Directory) always return 0 regardless if dir is empty or contain shortcuts (.lnk, .url).
Code: Select all
Procedure.s GetSpecialFolder(CSIDL.l)
Protected *itemid.ITEMIDLIST
Protected location.s = Space(#MAX_PATH)
If SHGetSpecialFolderLocation_ (0, CSIDL, @*itemid) = #NOERROR
If SHGetPathFromIDList_(*itemid, @location)
If Right(location, 1) <> "\" : location + "\" : EndIf
ProcedureReturn location
EndIf
EndIf
EndProcedure
programs.s = GetSpecialFolder(#CSIDL_PROGRAMS)
If ExamineDirectory(0, programs, "*.*")
While NextDirectoryEntry(0)
If DirectoryEntryType(0) = #PB_DirectoryEntry_Directory
If DirectoryEntryName(Dir) <> "." And DirectoryEntryName(Dir) <> ".."
Debug DirectoryEntryName(0) + Type$ + "- Size in byte: " + Str(DirectoryEntrySize(0))
EndIf
EndIf
Wend
FinishDirectory(0)
EndIf
Posted: Fri Feb 01, 2008 12:40 am
by oridan
Hi eJan, try with my code:
Code: Select all
Global TotalSize.q
Procedure.s Convert(byte.q, NbDecimals.l=2)
If byte < 1024
If byte < 0
byte=0
EndIf
ProcedureReturn ReplaceString(Str(byte)+" Byte", ".", ",")
ElseIf byte >= 1<<60
ProcedureReturn ReplaceString(StrD(byte/1<<60, NbDecimals)+" EB", ".", ",")
ElseIf byte >= 1<<50
ProcedureReturn ReplaceString(StrD(byte/1<<50, NbDecimals)+" PB", ".", ",")
ElseIf byte >= 1<<40
ProcedureReturn ReplaceString(StrD(byte/1<<40, NbDecimals)+" TB", ".", ",")
ElseIf byte >= 1<<30
ProcedureReturn ReplaceString(StrD(byte/1<<30, NbDecimals)+" GB", ".", ",")
ElseIf byte >= 1<<20
ProcedureReturn ReplaceString(StrD(byte/1<<20, NbDecimals)+" MB", ".", ",")
Else
ProcedureReturn ReplaceString(StrD(byte/1024, NbDecimals)+" KB", ".", ",")
EndIf
EndProcedure
Procedure.s GetSpecialFolder(CSIDL.l)
Protected *itemid.ITEMIDLIST
Protected location.s = Space(#MAX_PATH)
If SHGetSpecialFolderLocation_ (0, CSIDL, @*itemid) = #NOERROR
If SHGetPathFromIDList_(*itemid, @location)
If Right(location, 1) <> "\" : location + "\" : EndIf
ProcedureReturn location
EndIf
EndIf
EndProcedure
path$ = GetSpecialFolder(#CSIDL_PROGRAMS)
Procedure.q GET_CSIDL_PROGRAMS(path$,pattern$ = "*.*")
If Right(path$,1)<>"\":path$+"\":EndIf
DirID = ExamineDirectory(#PB_Any,path$,pattern$)
If DirID
While NextDirectoryEntry(DirID)
If DirectoryEntryType(DirID) = #PB_DirectoryEntry_Directory
If DirectoryEntryName(DirID)<>"." And DirectoryEntryName(DirID)<>".."
GET_CSIDL_PROGRAMS(path$+DirectoryEntryName(DirID)+"\",pattern$)
Debug DirectoryEntryName(DirID) + " = "+ Convert(TotalSize.q)
EndIf
EndIf
If DirectoryEntryType(DirID) = #PB_DirectoryEntry_File
TotalSize.q + DirectoryEntrySize(DirID)
EndIf
Wend
FinishDirectory(DirID)
EndIf
ProcedureReturn TotalSize.q
EndProcedure
GET_CSIDL_PROGRAMS(path$,"*.*")
Regards

Posted: Fri Feb 01, 2008 9:10 pm
by eJan
Thanks oridan, I doesn't work as espected in XP - for empty folder it returns 17,91 KB, another one with 2 subdirs 9,95 KB? until then i can always delete them manualy (i will try to to find some useful solution).

EDIT:
This dirty one works using API function 'RemoveDirectory_()'.
MSDN:
http://msdn2.microsoft.com/en-us/librar ... S.85).aspx
Should be tweaked to list only folders...
Code: Select all
; Trond: http://www.purebasic.fr/english/viewtopic.php?p=178764#178764
Procedure ExamineDirectoryRecursive(Path.s, Pattern.s, List.s())
Protected Dir = ExamineDirectory(#PB_Any, Path, Pattern)
If Right(Path, 1) <> "\"
Path + "\"
EndIf
If Dir
While NextDirectoryEntry(Dir)
If DirectoryEntryName(Dir) <> "." And DirectoryEntryName(Dir) <> ".."
AddElement(List())
List() = Path + DirectoryEntryName(Dir)
EndIf
Wend
FinishDirectory(Dir)
EndIf
Dir = ExamineDirectory(#PB_Any, Path, "")
If Dir
While NextDirectoryEntry(Dir)
If DirectoryEntryType(Dir) = #PB_DirectoryEntry_Directory
If DirectoryEntryName(Dir) <> "." And DirectoryEntryName(Dir) <> ".."
ExamineDirectoryRecursive(Path + DirectoryEntryName(Dir) + "\", Pattern, List())
EndIf
EndIf
Wend
FinishDirectory(Dir)
EndIf
EndProcedure
Procedure.s GetSpecialFolder(CSIDL.l)
Protected *itemid.ITEMIDLIST
Protected location.s = Space(#MAX_PATH)
If SHGetSpecialFolderLocation_ (0, CSIDL, @*itemid) = #NOERROR
If SHGetPathFromIDList_(*itemid, @location)
If Right(location, 1) <> "\" : location + "\" : EndIf
ProcedureReturn location
EndIf
EndIf
EndProcedure
programs.s = GetSpecialFolder(#CSIDL_PROGRAMS)
NewList List.s()
ExamineDirectoryRecursive(programs, "*.*", List())
ForEach List()
;Debug List()
RemoveDirectory_(List())
Next
Posted: Fri Feb 01, 2008 10:25 pm
by Trond
This should do it:
Code: Select all
Procedure ExamineDirectoryRecursive(Path.s, List.s())
Protected Dir
If Right(Path, 1) <> "\"
Path + "\"
EndIf
Dir = ExamineDirectory(#PB_Any, Path, "*.*")
If Dir
While NextDirectoryEntry(Dir)
If DirectoryEntryType(Dir) = #PB_DirectoryEntry_Directory
If DirectoryEntryName(Dir) <> "." And DirectoryEntryName(Dir) <> ".."
AddElement(List())
List() = Path + DirectoryEntryName(Dir)
ExamineDirectoryRecursive(Path + DirectoryEntryName(Dir) + "\", List())
EndIf
EndIf
Wend
FinishDirectory(Dir)
EndIf
EndProcedure
Procedure IsDirectoryEmpty(Dir.s)
Protected D = ExamineDirectory(#PB_Any, Dir, "*.*")
Protected I
If D
While NextDirectoryEntry(D)
I + 1
If I >= 3
FinishDirectory(D)
ProcedureReturn 0
EndIf
Wend
FinishDirectory(D)
ProcedureReturn 1
EndIf
EndProcedure
Procedure.s GetSpecialFolder(CSIDL.l)
Protected *itemid.ITEMIDLIST
Protected location.s = Space(#MAX_PATH)
If SHGetSpecialFolderLocation_ (0, CSIDL, @*itemid) = #NOERROR
If SHGetPathFromIDList_(*itemid, @location)
ProcedureReturn location
EndIf
EndIf
EndProcedure
programs.s = GetSpecialFolder(#CSIDL_PROGRAMS)
NewList List.s()
ExamineDirectoryRecursive(programs, List())
SortList(List(), 0)
ForEach List()
If IsDirectoryEmpty(List())
Debug List()
; DeleteDirectory(...
EndIf
Next
Posted: Sat Feb 02, 2008 1:35 pm
by eJan
Thanks Trond, this one works!
