Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
File List and Directory List (as array)
#1
Code: (Select All)
$Console:Only
ReDim Shared As String FileList(0), DirList(0)

Disk.File.List "", "" 'get a list of all files in the root directory
Disk.Dir.List "C:", "U*" 'get a list of all subdirectories that start with "U" from the root directory

For i = 1 To UBound(FileList)
    Print i, FileList(i)
Next

Sleep
_Delay .5
Cls
_KeyClear

For i = 1 To UBound(DirList)
    Print i, DirList(i)
Next
Sleep
System

Sub Disk.File.List (SearchDirectory As String, Extension As String)
    Dim As Long FileCount
    Dim As String Search, File, slash
    ReDim _Preserve FileList(1000) As String
    If SearchDirectory = "" Then SearchDirectory = _CWD$
    $If WIN Then
        slash = "\"
    $Else
        Slash = "/"
    $End If
    If Right$(SearchDirectory, 1) <> "/" _AndAlso Right$(SearchDirectory, 1) <> "\" Then SearchDirectory = SearchDirectory + slash
    If Extension = "" Then Extension = "*"
    Search = SearchDirectory + Extension
    File = _Files$(Search)
    Do While Len(File)
        File = SearchDirectory + File
        If _FileExists(File) Then
            FileCount = FileCount + 1
            If FileCount > UBound(FileList) Then ReDim _Preserve FileList(FileCount + 1000) As String
            FileList(FileCount) = File
        End If
        File = _Files$
    Loop
    ReDim _Preserve FileList(FileCount) As String
End Sub

Sub Disk.Dir.List (SearchDirectory As String, SearchFor As String)
    Dim As Long DirCount
    Dim As String Search, Dir, Slash
    ReDim _Preserve DirList(1000) As String
    If SearchDirectory = "" Then SearchDirectory = _CWD$
    $If WIN Then
        Slash = "\"
    $Else
        Slash = "/"
    $End If
    If Right$(SearchDirectory, 1) <> "/" _AndAlso Right$(SearchDirectory, 1) <> "\" Then SearchDirectory = SearchDirectory + Slash
    Search = SearchDirectory + SearchFor
    Dir = _Files$(Search)
    Do While Len(Dir)
        Dir = SearchDirectory + Dir
        If _DirExists(Dir) Then
            DirCount = DirCount + 1
            If DirCount > UBound(DirList) Then ReDim _Preserve DirList(UBound(DirList) + 1000) As String
            DirList(DirCount) = Dir
        End If
        Dir = _Files$
    Loop
    ReDim _Preserve DirList(DirCount) As String
End Sub

Updated to make use of the new _FILES$ command so this doesn't need any external libraries or anything to run.
What it does is give you a quick listing of files or directory into a shared set of arrays called FileList() and DirList().

Usage is rather simple as shown in the demo here.  If anyone has questions, feel free to ask.  Wink



EDIT:  I'd suggest using the version below for extended flexibility and control over your return data. https://qb64phoenix.com/forum/showthread...2#pid39082

In my personal opinion, the version in post #7 is much better than this version, especially once you start mixing and matching how the flag return values work for you.  Wink
Reply
#2
Thank you! It's nice not having to rely on that header file.
Reply
#3
Code: (Select All)
$Console:Only
ReDim As String FileList(0)

Disk.File.List "", "", -1, FileList() 'get a list of all files in the root directory
For i = 1 To UBound(FileList)
    Print i, FileList(i)
Next

Sub Disk.File.List (SearchDir As String, Extension As String, Flag As Long, ReturnArray() As String)
    'flags are binary bits which represent the following
    'Note that a quick value of -1 will set all bits and return everything for us
    '1 -- file listing
    '2 -- directory listing
    '4 -- sorted (directory before file, like windows explorer does) -- implies 1 + 2 both are wanted.
    '8 -- return full path info
    Dim As Long FileCount, pass
    Dim As String Search, File, Slash
    ReDim ReturnArray(1000) As String
    If SearchDir = "" Then SearchDir = _CWD$: If Extension = "" Then Extension = "*"
    If InStr(_OS$, "WIN") Then Slash = "\" Else Slash = "/"
    If Right$(SearchDir, 1) <> "/" _AndAlso Right$(SearchDir, 1) <> "\" Then SearchDir = SearchDir + Slash
    Search = SearchDir + Extension
    If Flag And 4 Then 'sorted so we get directory listings then files
        For pass = 1 To 2 'two passes, first to get directory listings then files
            File = _Files$(Search)
            Do While Len(File)
                If ((pass = 1) _AndAlso _DirExists(SearchDir + File)) _OrElse ((pass = 2) _AndAlso _FileExists(SearchDir + File)) Then
                    FileCount = FileCount + 1
                    If FileCount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(FileCount + 1000) As String
                    If Flag And 8 Then File = SearchDir + File 'we want the full path info
                    ReturnArray(FileCount) = File
                End If
                File = _Files$
            Loop
        Next
    Else 'unsorted so files and directories are simply listed in alphabetical order
        File = _Files$(Search) 'one single pass where we just grab all the info at once
        Do While Len(File)
            If ((Flag And 1) _AndAlso _FileExists(SearchDir + File)) _OrElse ((Flag And 2) _AndAlso _DirExists(SearchDir + File)) Then
                FileCount = FileCount + 1
                If FileCount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(FileCount + 1000) As String
                If Flag And 8 Then File = SearchDir + File 'we want the full path info
                ReturnArray(FileCount) = File
            End If
            File = _Files$
        Loop
    End If
    ReDim _Preserve ReturnArray(FileCount) As String
End Sub

Note:  I'd suggest folks make use of this version instead of the above.  It's a much more powerful version and can do multiple things for us that the above couldn't do.  This will get files, get directories, allow you to choose between full paths or short paths, and will even sort them if you desire.  What more could you possibly want from a file listing tool?  Big Grin
Reply
#4
This is 100% awesome.  No fillers, no junk, no extra calories...Thank you !!!
Reply
#5
Expanded to finally add a recursive directory ability into this.

Code: (Select All)
ReDim As String FileList(0) 'be certain to reset your file listing to 0 files like this, before calling the recursive version

Disk.File.List.Recursive "C:\My Stuff\", "", FileList() 'get a list of all files in the directory, plus subdirectories
For i = 1 To UBound(FileList)
Print i, FileList(i)
Next

Sub Disk.File.List.Recursive (SearchDir As String, Extension As String, ReturnArray() As String)
ReDim TempArray(0) As String
Dim As Long i, totalcount
totalcount = UBound(ReturnArray)
Disk.File.List SearchDir, Extension, -1, TempArray() 'get a temp array of data
For i = 1 To UBound(TempArray)
totalcount = totalcount + 1
If totalcount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(totalcount + 10000) As String
ReturnArray(totalcount) = TempArray(i)
Next
ReDim _Preserve ReturnArray(totalcount) As String
For i = 1 To UBound(TempArray)
If _DirExists(TempArray(i)) Then Disk.File.List.Recursive TempArray(i), Extension, ReturnArray() 'get a temp array of data
Next
End Sub

Sub Disk.File.List (SearchDir As String, Extension As String, Flag As Long, ReturnArray() As String)
'flags are binary bits which represent the following
'Note that a quick value of -1 will set all bits and return everything for us
'1 -- file listing
'2 -- directory listing
'4 -- sorted (directory before file, like windows explorer does) -- implies 1 + 2 both are wanted.
'8 -- return full path info
Dim As Long FileCount, pass
Dim As String Search, File, Slash
ReDim ReturnArray(1000) As String
If SearchDir = "" Then SearchDir = _CWD$: If Extension = "" Then Extension = "*"
If InStr(_OS$, "WIN") Then Slash = "\" Else Slash = "/"
If Right$(SearchDir, 1) <> "/" _AndAlso Right$(SearchDir, 1) <> "\" Then SearchDir = SearchDir + Slash
Search = SearchDir + Extension
If Flag And 4 Then 'sorted so we get directory listings then files
For pass = 1 To 2 'two passes, first to get directory listings then files
File = _Files$(Search)
Do While Len(File)
If File = ".\" _OrElse File = "..\" Then

Else
If ((pass = 1) _AndAlso _DirExists(SearchDir + File)) _OrElse ((pass = 2) _AndAlso _FileExists(SearchDir + File)) Then
FileCount = FileCount + 1
If FileCount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(FileCount + 1000) As String
If Flag And 8 Then File = SearchDir + File 'we want the full path info
ReturnArray(FileCount) = File
End If
End If
File = _Files$
Loop
Next
Else 'unsorted so files and directories are simply listed in alphabetical order
File = _Files$(Search) 'one single pass where we just grab all the info at once
Do While Len(File)
If File = ".\" _OrElse File = "..\" Then

Else
If ((Flag And 1) _AndAlso _FileExists(SearchDir + File)) _OrElse ((Flag And 2) _AndAlso _DirExists(SearchDir + File)) Then
FileCount = FileCount + 1
If FileCount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(FileCount + 1000) As String
If Flag And 8 Then File = SearchDir + File 'we want the full path info
ReturnArray(FileCount) = File
End If
End If
File = _Files$
Loop
End If
ReDim _Preserve ReturnArray(FileCount) As String
End Sub

Note that the recursive routine doesn't allow you to set a flag to just get back short names or files or directories. It looks at a folder, grabs all the information from it, and then grabs all the information from the subfolders. If you want to filter out files or directories, that's on you; this doesn't bother to do that for you.

IMPORTANT USE NOTE: Be certain to reset your array to blank before using the recursive routine. It makes several passes and builds upon the previous pass to generate your results. If you send it an array that already has stuff in it, it'll just add to that array, rather than erasing it.

ReDim As String FileList(0) 'be certain to reset your file listing to 0 files like this, before calling the recursive version
THEN call then recursive routine to get the list of files and folders recursively for you.
Reply
#6
(01-20-2026, 09:20 AM)SMcNeill Wrote: Expanded to finally add a recursive directory ability into this.


Note that the recursive routine doesn't allow you to set a flag to just get back short names or files or directories.  It looks at a folder, grabs all the information from it, and then grabs all the information from the subfolders.  If you want to filter out files or directories, that's on you; this doesn't bother to do that for you. 

IMPORTANT USE NOTE:  Be certain to reset your array to blank before using the recursive routine.  It makes several passes and builds upon the previous pass to generate your results.  If you send it an array that already has stuff in it, it'll just add to that array, rather than erasing it.

ReDim As String FileList(0) 'be certain to reset your file listing to 0 files like this, before calling the recursive version
THEN call then recursive routine to get the list of files and folders recursively for you.

And when you thought it could not get any better...<BAM>
Thanks again Steve - this is great and I just might replace my ages old SHELL with DIR to a file and then comb through it...
Reply
#7
Code: (Select All)
Option _Explicit

ReDim As String FileList(0), f ' be certain to reset your file listing to 0 files like this, before calling the recursive version
Dim i As Long


Disk.File.List "Z:\", "", -1, FileList() ' get a list of all files in the directory, plus subdirectories
For i = 0 To UBound(FileList)
Print i, FileList(i)
Next
f = ".png,.gif" ' comma separated extensions
Disk.File.List.FilterForExtension FileList(), f 'get your file list before you try to filter it. Big Grin
Print "Filtered"
For i = 0 To UBound(FileList)
Print i, FileList(i)
Next

Sub Disk.File.List.FilterForExtension (FileList() As String, filter As String)
'note that I haven't added filers for wild cards and such, this is for set patterns, with a comma delimiter
Dim As String temp, process
ReDim As String filters(1000), tempList(0)
Dim As Long i, j, p, count, listCount
temp = filter
Do
p = InStr(temp, ",")
If p Then
process$ = Left$(temp, p - 1) 'strip off the symbols
temp = Mid$(temp, p + 1)
Else
process$ = temp
End If
count = count + 1 'the number of filters
filters(count) = process$
Loop Until process$ = temp

ReDim tempList(UBound(FileList)) As String

For i = 1 To UBound(FileList)
temp = FileList(i)
For j = 1 To count
If InStr(temp, filters(j)) Then
listCount = listCount + 1
tempList(listCount) = FileList(i)
Exit For 'no need to keep looking, we found an item that matches our search criteria
End If
Next
Next
For i = 1 To listCount: FileList(i) = tempList(i): Next
ReDim _Preserve FileList(listCount) As String
End Sub


Sub Disk.File.List.Recursive (SearchDir As String, Extension As String, ReturnArray() As String)
ReDim TempArray(0) As String
Dim As Long i, totalcount
totalcount = UBound(ReturnArray)
Disk.File.List SearchDir, Extension, -1, TempArray() 'get a temp array of data
For i = 1 To UBound(TempArray)
totalcount = totalcount + 1
If totalcount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(totalcount + 10000) As String
ReturnArray(totalcount) = TempArray(i)
Next
ReDim _Preserve ReturnArray(totalcount) As String
For i = 1 To UBound(TempArray)
If _DirExists(TempArray(i)) Then Disk.File.List.Recursive TempArray(i), Extension, ReturnArray() 'get a temp array of data
Next
End Sub

Sub Disk.File.List (SearchDir As String, Extension As String, Flag As Long, ReturnArray() As String)
'flags are binary bits which represent the following
'Note that a quick value of -1 will set all bits and return everything for us
'1 -- file listing
'2 -- directory listing
'4 -- sorted (directory before file, like windows explorer does) -- implies 1 + 2 both are wanted.
'8 -- return full path info
Dim As Long FileCount, pass
Dim As String Search, File, Slash
ReDim ReturnArray(1000) As String
If SearchDir = "" Then SearchDir = _CWD$: If Extension = "" Then Extension = "*"
If InStr(_OS$, "WIN") Then Slash = "\" Else Slash = "/"
If Right$(SearchDir, 1) <> "/" _AndAlso Right$(SearchDir, 1) <> "\" Then SearchDir = SearchDir + Slash
Search = SearchDir + Extension
If Flag And 4 Then 'sorted so we get directory listings then files
For pass = 1 To 2 'two passes, first to get directory listings then files
File = _Files$(Search)
Do While Len(File)
If File = ".\" _OrElse File = "..\" Then

Else
If ((pass = 1) _AndAlso _DirExists(SearchDir + File)) _OrElse ((pass = 2) _AndAlso _FileExists(SearchDir + File)) Then
FileCount = FileCount + 1
If FileCount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(FileCount + 1000) As String
If Flag And 8 Then File = SearchDir + File 'we want the full path info
ReturnArray(FileCount) = File
End If
End If
File = _Files$
Loop
Next
Else 'unsorted so files and directories are simply listed in alphabetical order
File = _Files$(Search) 'one single pass where we just grab all the info at once
Do While Len(File)
If File = ".\" _OrElse File = "..\" Then

Else
If ((Flag And 1) _AndAlso _FileExists(SearchDir + File)) _OrElse ((Flag And 2) _AndAlso _DirExists(SearchDir + File)) Then
FileCount = FileCount + 1
If FileCount > UBound(ReturnArray) Then ReDim _Preserve ReturnArray(FileCount + 1000) As String
If Flag And 8 Then File = SearchDir + File 'we want the full path info
ReturnArray(FileCount) = File
End If
End If
File = _Files$
Loop
End If
ReDim _Preserve ReturnArray(FileCount) As String
End Sub

Add in one more feature to this which others might find useful -- the ability to filter the file list into a set of extensions.

If the _FILES$ command works with more than one set of filters, I don't know the syntax for it and it's not documented anywhere.

We can filter our command to look for all *.bas files, but I know of no way to look for (*.bas, *.bi, *.bm, *.h, *.txt) all in one go. So my work around is to just grab everything and then filter for those extensions all at once with the new command here.

I think the code above should showcase how to make use of it, if you want to give it a go. (Note that I'm not checking for wildcards and such here; this is just a filter for extensions so I can quickly gather other image types or all movie types or all fonts, ect.)
Reply
#8
This is very nice and useful. Let me contribute a little. This very simple program will list the valid disk drives of the computer.

Code: (Select All)

ReDim Drives(0) As String
GetDriveList Drives()

Print "Found drives:"
For f = 0 To UBound(Drives) 
    Print Drives(f)
Next

End



Sub GetDriveList (drives() As String)
    Dim c As Long
    Dim letter As String
    Dim root As String

    ReDim drives(0) As String
    dCount = 0

    $If WINDOWS Then
        c = 65
        While c <= 90
            letter = Chr$(c)
            root = letter + ":\"
            If _DirExists(root) Then
                drives(dCount) = root
                dCount = dCount + 1
                ReDim _Preserve drives(dCount) As String
            End If
            c = c + 1
        Wend
    $End If
End Sub


Reply
#9
Code: (Select All)
#include <vector>
#include <string>
#include <filesystem>
#include <algorithm>
#include <cstring>
#include <cstdint>

namespace fs = std::filesystem;

extern "C" {
    struct Node {
        std::string name, path;
        int64_t size;
        bool is_dir;
    };

    std::vector<Node*> vault;
    fs::recursive_directory_iterator it;
    bool is_crawling = false;
   
    // Safety Buffers for String Exchange
    static char name_buf[1024];
    static char path_buf[2048];
    static char live_buf[2048];

    // Main Engine
    __declspec(dllexport) void Pimp_Start(const char* root, int32_t recursive) {
        for(auto n : vault) delete n;
        vault.clear();
        std::error_code ec;
        fs::path p(root);
       
        if (p.has_parent_path() && p != p.root_path()) {
            vault.push_back(new Node{".. [Go Back]", p.parent_path().string(), 0, true});
        }

        if (recursive) {
            it = fs::recursive_directory_iterator(root, fs::directory_options::skip_permission_denied, ec);
            is_crawling = !ec;
        } else {
            for (const auto& entry : fs::directory_iterator(root, ec)) {
                if (ec) { ec.clear(); continue; }
                vault.push_back(new Node{entry.path().filename().string(), entry.path().string(),
                                         entry.is_directory() ? 0 : (int64_t)fs::file_size(entry, ec), entry.is_directory()});
            }
            is_crawling = false;
        }
    }

    __declspec(dllexport) int32_t Pimp_Pulse() {
        if (!is_crawling || it == fs::recursive_directory_iterator()) return 0;
        std::error_code ec;
        try {
            const auto& entry = *it;
            vault.push_back(new Node{entry.path().filename().string(), entry.path().string(),
                                     entry.is_directory() ? 0 : (int64_t)fs::file_size(entry, ec), entry.is_directory()});
            strncpy(live_buf, entry.path().string().c_str(), 2047);
            it.increment(ec);
            if (ec) is_crawling = false;
        } catch (...) { return 0; }
        return 1;
    }

    __declspec(dllexport) void Pimp_Sort() {
        if (vault.size() < 2) return;
        std::sort(vault.begin(), vault.end(), [](Node* a, Node* b) {
            if (a->name.find("..") != std::string::npos) return true;
            if (b->name.find("..") != std::string::npos) return false;
            if (a->is_dir != b->is_dir) return a->is_dir > b->is_dir;
            return a->name < b->name;
        });
    }

    __declspec(dllexport) int32_t Pimp_Count() { return (int32_t)vault.size(); }
    __declspec(dllexport) const char* Pimp_GetName(int32_t i) { strncpy(name_buf, vault[i]->name.c_str(), 1023); return name_buf; }
    __declspec(dllexport) const char* Pimp_GetPath(int32_t i) { strncpy(path_buf, vault[i]->path.c_str(), 2047); return path_buf; }
    __declspec(dllexport) int64_t Pimp_GetSize(int32_t i) { return vault[i]->size; }
    __declspec(dllexport) bool Pimp_IsDir(int32_t i) { return vault[i]->is_dir; }
    __declspec(dllexport) const char* Pimp_GetLive() { return live_buf; }
}
Save that as FS_Pimped.h in your Qb64 folder and then 

Code: (Select All)
' //////////////////////////////////////////////////////////////////////////////////////////////////////
' // S-TIER VFS MASTER (2026 FORUM RELEASE)
' // Optimized for 800x600 Laptop Screens
' //////////////////////////////////////////////////////////////////////////////////////////////////////

' Declare using the shared library name (renamed manually by user if 32 or 64 bit)
DECLARE LIBRARY "FS_Pimped"
  SUB Pimp_Start (path AS STRING, BYVAL recursive AS LONG)
  FUNCTION Pimp_Pulse& ()
  FUNCTION Pimp_GetLive$ ()
  SUB Pimp_Sort ()
  FUNCTION Pimp_Count& ()
  FUNCTION Pimp_GetName$ (BYVAL index AS LONG)
  FUNCTION Pimp_GetPath$ (BYVAL index AS LONG)
  FUNCTION Pimp_GetSize&& (BYVAL index AS LONG)
  FUNCTION Pimp_IsDir%% (BYVAL index AS LONG)
END DECLARE

SCREEN _NEWIMAGE(800, 600, 32)
fnt& = _LOADFONT("C:\windows\fonts\consola.ttf", 16): _FONT fnt&

DIM SHARED Path$, MenuRef, ViewOffset, MaxView
Path$ = "C:\"
MenuRef = 0: ViewOffset = 0: MaxView = 22

Pimp_Start Path$ + CHR$(0), 0: Pimp_Sort

DO
  _LIMIT 60: CLS: Count& = Pimp_Count&

  ' UI Header
  COLOR _RGB32(0, 255, 120): PRINT " S-TIER VFS MASTER 2026 | "; Path$
  COLOR _RGB32(70, 70, 70): PRINT STRING$(80, "-")

  ' --- MOUSE & INPUT HUB ---
  DO WHILE _MOUSEINPUT
    mx = _MOUSEX: my = _MOUSEY: ml = _MOUSEBUTTON(1): mw = _MOUSEWHEEL

    ' Synchronized Scroll Wheel
    IF mw <> 0 THEN
      MenuRef = MenuRef + mw: IF MenuRef < 0 THEN MenuRef = 0
      IF MenuRef > Count& - 1 THEN MenuRef = Count& - 1
      IF MenuRef < ViewOffset THEN ViewOffset = MenuRef
      IF MenuRef >= ViewOffset + MaxView THEN ViewOffset = MenuRef - MaxView + 1
    END IF

    ' Hover Selection
    IF mx <> lastMX OR my <> lastMY THEN
      FOR i = 0 TO MaxView - 1
        yT = 70 + (i * 20): yB = yT + 20
        IF mx > 20 AND mx < 530 AND my > yT AND my < yB THEN
          hIdx = ViewOffset + i: IF hIdx < Count& THEN MenuRef = hIdx
        END IF
      NEXT
    END IF
    lastMX = mx: lastMY = my

    ' Click to Drill Down
    IF ml AND Count& > 0 THEN
      IF Pimp_IsDir%%(MenuRef) THEN
        Path$ = Pimp_GetPath$(MenuRef): Pimp_Start Path$ + CHR$(0), 0: Pimp_Sort
        MenuRef = 0: ViewOffset = 0: _DELAY .2
      END IF
    END IF
  LOOP

  ' --- LIST RENDER ---
  FOR i = 0 TO MaxView - 1
    idx& = ViewOffset + i: IF idx& >= Count& THEN EXIT FOR
    y = 70 + (i * 20)
    IF idx& = MenuRef THEN
      COLOR _RGB32(0, 0, 0), _RGB32(0, 255, 200): _PRINTSTRING (20, y), " > " + LEFT$(Pimp_GetName(idx&), 55)
      COLOR _RGB32(255, 255, 255), _RGB32(0, 0, 0)
    ELSE
      IF Pimp_IsDir%%(idx&) THEN COLOR _RGB32(255, 255, 0) ELSE COLOR _RGB32(180, 180, 180)
      _PRINTSTRING (20, y), "  " + LEFT$(Pimp_GetName(idx&), 55)
    END IF
  NEXT

  ' --- SIDEBAR ---
  LINE (550, 70)-(785, 530), _RGB32(25, 25, 35), BF
  COLOR _RGB32(0, 255, 255): _PRINTSTRING (565, 90), "[ FILE DATA ]"
  COLOR _RGB32(255, 255, 255): _PRINTSTRING (565, 130), "Size: " + STR$(Pimp_GetSize&&(MenuRef))
  _PRINTSTRING (565, 500), "[F]ind  [ESC] Exit"

  ' Viewport Auto-Clamp
  IF MenuRef < ViewOffset THEN ViewOffset = MenuRef
  IF MenuRef >= ViewOffset + MaxView THEN ViewOffset = MenuRef - MaxView + 1

  ' Hotkeys
  k$ = INKEY$
  IF LCASE$(k$) = "f" THEN RunSearchDialog
  _DISPLAY
LOOP UNTIL k$ = CHR$(27)
SYSTEM

' //////////////////////////////////////////////////////////////////////////////////////////////////////

SUB RunSearchDialog
  SearchStr$ = ""
  DO ' Phase 1: Custom Dialog Input
    _LIMIT 60: CLS: LINE (150, 200)-(650, 350), _RGB32(40, 40, 50), BF
    LINE (150, 200)-(650, 350), _RGB32(0, 255, 255), B
    COLOR _RGB32(255, 255, 255): _PRINTSTRING (170, 220), "Enter Filename Pattern:"
    _PRINTSTRING (170, 250), "> " + SearchStr$ + "_"
    _PRINTSTRING (170, 320), "[ENTER] Scan | [ESC] Cancel"

    c$ = INKEY$
    IF c$ = CHR$(13) THEN EXIT DO
    IF c$ = CHR$(27) THEN EXIT SUB
    IF c$ = CHR$(8) AND LEN(SearchStr$) > 0 THEN SearchStr$ = LEFT$(SearchStr$, LEN(SearchStr$) - 1)
    IF LEN(c$) = 1 AND c$ >= " " THEN SearchStr$ = SearchStr$ + c$
    _DISPLAY
  LOOP

  ' Phase 2: Async Recursive Pulse
  Pimp_Start Path$ + CHR$(0), 1
  ScanDone = 0
  DO
    FOR p = 1 TO 400
      IF Pimp_Pulse& = 0 THEN
        ScanDone = 1
        EXIT FOR
      END IF
    NEXT
    IF ScanDone = 1 THEN EXIT DO

    CLS: LINE (100, 200)-(700, 405), _RGB32(40, 40, 50), BF
    LINE (100, 200)-(700, 405), _RGB32(255, 50, 50), B
    COLOR _RGB32(255, 255, 255): _PRINTSTRING (120, 220), "DEEP SCAN IN PROGRESS..."
    _PRINTSTRING (120, 250), "TARGET: " + SearchStr$
    _PRINTSTRING (120, 280), "FOUND:  " + STR$(Pimp_Count&)
    COLOR _RGB32(150, 150, 150): _PRINTSTRING (120, 330), "DIR: " + LEFT$(Pimp_GetLive$, 68)
    COLOR _RGB32(255, 200, 0): _PRINTSTRING (120, 380), "[ESC] TO STOP AND BROWSE"
    IF INKEY$ = CHR$(27) THEN EXIT DO
    _DISPLAY: _LIMIT 60
  LOOP
  Pimp_Sort: MenuRef = 0: ViewOffset = 0
END SUB

It aint perfect, but it works FAST AS F! Mouse works (wheel up and down is slightly dodgy though!) Press F to search for a file or format...please mod, edit hack and cuss it out as you feel (i think i made this so it should work on 32 and 64 bit qb64 too so id like to know if that effort failed!)

Unseen
Reply
#10
@Petr

If you're looking for a windows only drive routine, give this one a try and see what it tells you:

Code: (Select All)
Screen _NewImage(800, 600, 32)

Type DriveInfo
    Root As String * 16
    Label As String * 128
    UsedGB As _Integer64
    FreeGB As _Integer64
End Type

ReDim Drives(0) As DriveInfo
Dim count As Integer

Call GetDriveInfo(Drives())

Print "Drive", "Label";
Locate , 40: Print "Used (GB)", "", "Free (GB)"

For i = 0 To UBound(Drives)
    Print RTrim$(Drives(i).Root),
    Print RTrim$(Drives(i).Label);
    Locate , 40
    Print Using "###,###.### GB"; Drives(i).UsedGB / _ONE_GB,
    Print "", Using "###,###.### GB"; Drives(i).FreeGB / _ONE_GB
Next

Sub GetDriveInfo (drives() As DriveInfo)
    Dim As String tempPath, psCmd
    Dim ff As Integer
    tempPath = "tempdrives.txt"
    psCmd = "cmd /c powershell -Command " + Chr$(34)
    psCmd = psCmd + "$drives = Get-PSDrive -PSProvider 'FileSystem'; "
    psCmd = psCmd + "foreach ($d in $drives) { "
    psCmd = psCmd + "$label = if ([string]::IsNullOrWhiteSpace($d.DisplayRoot)) { 'None' } else { $d.DisplayRoot }; "
    psCmd = psCmd + "$fields = @($d.Root, $label, $d.used, $d.free); "
    psCmd = psCmd + "Write-Output $fields }"
    psCmd = psCmd + Chr$(34) + " > " + tempPath
    Shell _Hide psCmd
    ff = FreeFile: Open tempPath For Input As #ff
    ReDim drives(100) As DriveInfo
    Do While Not EOF(ff)
        Input #ff, drives(count).Root, drives(count).Label, drives(count).UsedGB, drives(count).FreeGB
        count = count + 1
    Loop
    If count > 0 Then ReDim _Preserve drives(count - 1) As DriveInfo
    Close #ff
    Kill tempPath
End Sub


Here's my general output:
Code: (Select All)
Drive    Label                         Used (GB)           Free (GB)
C:\      None                              737.200 GB        1,143.500 GB
X:\      \\10.243.1.1\My Book Duo        6,449.300 GB       15,902.700 GB
Z:\      None                                0.000 GB           12.000 GB

Press any key to continue

Notice that it also has my network drive (X: ), which is mapped to the \\10.243.1.1\ network path, as well as my local hard drive and my ramdrive (Z: ).

It has a little more info that just "What drives are there," as it also tells you used space and free space, which might also be nice for you to know sometime with your stuff.

Give it a test run and let me know how it works out for you.  Wink  Let me know if it doesn't work, as it seems a little quirky with command and shell and powershell and whether it wants to shell out to a terminal or a console or just crap up sometimes.  Something with SHELL just doesn't always want to play 100% reliable, unless you just tweak the command absolutely perfect.

SHELL "cmd /c powershell -command"   <-- this seems redundant to me and unnecessary, but it's the only odd combination which seems to work unless I'm in a console window to start with.  So we shell to command to run powershell to run the script.  /sigh 

And if that makes sense to anyone else, kindly explain it to me.  WTF wouldn't SHELL "powershell - command" work just as easily?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Windows Font List SMcNeill 27 6,197 01-20-2026, 05:50 PM
Last Post: SMcNeill
  Book List to Folders SMcNeill 5 1,520 11-27-2023, 06:51 PM
Last Post: Dimster
  Word Count / Word List Generator SMcNeill 0 679 04-20-2022, 02:35 AM
Last Post: SMcNeill

Forum Jump:


Users browsing this thread: 1 Guest(s)