Finding files using cmd.exe + Dir

Share your advanced PureBasic knowledge/code with the community.
AZJIO
Addict
Addict
Posts: 2191
Joined: Sun May 14, 2017 1:48 am

Finding files using cmd.exe + Dir

Post by AZJIO »

Code: Select all

EnableExplicit

; https://www.purebasic.fr/english/viewtopic.php?f=12&t=65159&p=486382&hilit=SplitL#p486382
Procedure SplitL(String.s, List StringList.s(), Separator.s = " ")
	
	Protected S.String, *S.Integer = @S
	Protected.i p, slen
	slen = Len(Separator)
	ClearList(StringList())
	
	*S\i = @String
	Repeat
		AddElement(StringList())
		p = FindString(S\s, Separator)
		StringList() = PeekS(*S\i, p - 1)
		*S\i + (p + slen - 1) << #PB_Compiler_Unicode
	Until p = 0
	*S\i = 0
	
EndProcedure

; #FUNCTION# ====================================================================================================
; Name...........:	FileDirListCmd
; Description....:	Search files and\or folders in a specified path (uses system Dir command)
; Syntax.........:	FileDirListCmd(List FileListOut.s(), Path$ [, FileMask$ = "*" [, Flag = 0 [, SubDir = 1 [, Sort = 0]]]])
; Parameters.....:	List FileListOut.s()     - The list where the result will be placed
;					Path$     - Path To search the file.
;					FileMask$ - [Optional] Filter to use, default is "*" (WildCards).
;					Flag     - [Optional] Specifies whether to return files folders or both:
;                                                                                               Flag = 0 - Files and folders (default)
;                                                                                               Flag = 1 - Only files
;                                                                                               Flag = 2 - Only folders
;					SubDir   - [Optional] Specifies whether to search in subfolders or not:
;                                                                                               SubDir = 1 - Search in subfolders (default). Returns full pathes.
;                                                                                               SubDir = 0 - Search without subfolders (only in Path$). Returns filenames only.
;					Sort     - [Optional] Specifies whether to sort the output list (in alphabetic order) or not (default is 0 - do not sort). Case-insensitive sorting.
;					
; Return values..:	Success    - Returns the number of elements found. The FileListOut() list contains the found elements.
;					Failure    - number less than zero
;                                 -1 = Path not found or invalid
;                                 -2 = Exitcode returns an error
;                                 -3 = Программа 
;
; Author.........: 	G.Sandler (CreatoR), amel27. (script in AutoIt3)
; Modified.......:	 AZJIO rewrote AutoIt3 code to PureBasic
; Remarks........:	This function uses system Dir command, to speed up the search.
; Related........:	
; Link...........:	https://autoit-script.ru/threads/_FileDirListCmd-poisk-fajlov-s-ispolzovaniem-komandy-dir.8266/
; Example........:	
; ===============================================================================================================
Procedure FileDirListCmd(List FileListOut.s(), Path$, FileMask$ = "*", Flag = 0, SubDir = 1, Sort = 0)
	Protected sOutBin$, Out$, hDir, Attrib$, Files$, Exitcode = -3, pos
	Protected NewList LstMasks$()
	
	If FileSize(Path$) <> -2
		ProcedureReturn -1
	EndIf
	
	If SubDir = 1
		Attrib$ + " /S"
	EndIf
	
	If Sort = 1
		Attrib$ + " /O:N"
	EndIf

	Select Flag
		Case 1
			Attrib$ + " /A-D"
		Case 2 
			Attrib$ + " /AD"
		Default 
			Attrib$ + " /A"
	EndSelect

; 	Out$ = StringToBinary("0" + #CRLF$, 2)
	Path$ = RTrim(Path$, #PS$)
	FileMask$ = Trim(FileMask$, ";")
	Repeat
		pos = FindString(FileMask$, ";;")
		If pos
			FileMask$ = ReplaceString(FileMask$, ";;", ";")
		EndIf
	Until Not pos
	SplitL(FileMask$, LstMasks$(), ";")
	
	ForEach LstMasks$()
		Files$ + Chr(34) + Path$ + #PS$ + LstMasks$() + Chr(34) + ";"
	Next
	Files$ = RTrim(Files$, ";")

	hDir = RunProgram(GetEnvironmentVariable("ComSpec"), ; cmd.exe
; 	                   "/u /c (DIR " + Files$ + " /B" + Attrib$ + ")", "",
	                   "/u /c DIR " + Files$ + " /B" + Attrib$, "",
	                   #PB_Program_Open | #PB_Program_Read | #PB_Program_Error | #PB_Program_Unicode | #PB_Program_Hide)
	If hDir
		While ProgramRunning(hDir)
			If AvailableProgramOutput(hDir)
				Out$ + ReadProgramString(hDir) + Chr(13)
			EndIf
		Wend
		Exitcode = ProgramExitCode(hDir)
		CloseProgram(hDir)
	EndIf
	If Exitcode
		ProcedureReturn -2
	EndIf
	Out$ = RTrim(Out$, #CR$)

	SplitL(Out$, FileListOut(), #CR$)

	ProcedureReturn ListSize(FileListOut())
EndProcedure


Define NewList Files.s()
; Debug FileDirListCmd(Files(), #PB_Compiler_Home + "SDK\DocMaker", "*.txt;*.exe", 0, 2, 0) ; Flag, SubDir, Sort
; Debug FileDirListCmd(Files(), #PB_Compiler_Home + "SDK\DocMaker", "*", 1, 1, 1)
Debug FileDirListCmd(Files(), #PB_Compiler_Home + "Examples\3D\Data", "*.ogg;*.zip", 1, 1, 0)

ForEach Files()
	Debug Files()
Next
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5494
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Finding files using cmd.exe + Dir

Post by Kwai chang caine »

That works here :wink:
Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
User avatar
electrochrisso
Addict
Addict
Posts: 989
Joined: Mon May 14, 2007 2:13 am
Location: Darling River

Re: Finding files using cmd.exe + Dir

Post by electrochrisso »

Does a lot for a small amount of code.
Good Job.
:)
PureBasic! Purely the best 8)
Post Reply