Microsoft KB Archive/41447

= Examples of Loading MS-DOS Directory Listing into an Array =

Article ID: 41447

Article Last Modified on 8/16/2005

-

APPLIES TO


 * Microsoft Visual Basic for MS-DOS
 * Microsoft QuickBasic 4.0
 * Microsoft QuickBASIC 4.0b
 * Microsoft QuickBasic 4.5 for MS-DOS
 * Microsoft BASIC Compiler 6.0
 * Microsoft BASIC Compiler 6.0b
 * Microsoft BASIC Professional Development System 7.0
 * Microsoft BASIC Professional Development System 7.1

-



This article was previously published under Q41447



SUMMARY
This article discusses three different methods of putting an MS-DOS disk directory listing into a string array.

Example 1 demonstrates how to use the DIR$ function to read a directory listing into an array. This is probably the simplest method for use with Visual Basic for MS-DOS. The DIR$ functions was introduced in Microsoft Basic PDS for MS-DOS and MS OS/2, version 7.0. For an example of using the DIR$ function (which works in both MS-DOS and MS OS/2), query the Knowledge Base on the following keywords:

7.0 and &quot;DIR$&quot; and DIRECTORY and LISTING

Example 2 shows a simple method to SHELL to the MS-DOS DIR command, redirect the output to a file, and input from the file into string variables.

Example 3 below shows how to load an MS-DOS disk directory listing into a string array, using the CALL INTERRUPT statement to invoke the MS-DOS operating-system Interrupt 21h, with functions 1Ah (SetDTA), 4Eh (FindFirst), and 4Fh (FindNext).



MORE INFORMATION
For an example of calling the MS-DOS interrupt functions to obtain disk directory information in Microsoft QuickBasic for MS-DOS, versions 2.0, 2.01, or 3.0, query the Knowledge Base on the following keywords:

INT86.OBJ and FINDFIRST

For a Microsoft Basic PDS for MS-DOS and MS OS/2, version 7.0 or 7.1 or Microsoft Basic Compiler for MS-DOS and MS OS/2, version 6.0 or 6.0b example that displays directory information in MS OS/2 protected mode, query the Knowledge Base on the following keywords:

DosFindFirst or DosFindNext

Example 1
' To try this example in VBDOS.EXE: ' 1. From the File menu, choose New Project. ' 2. Copy the code example to the Code window. ' 3. Press F5 to run the program. DEFINT A-Z CONST TRUE = -1 CONST FALSE = NOT TRUE NumFiles = 255            ' Maximum number of filenames to hold. Counter = 0 Finished = FALSE DIM FileName$(NumFiles)

CLS    ' Enter DIR type filespec, for example &quot;C:\*.BAS&quot;: INPUT &quot;Enter filespec:&quot;; Path$ TempName$ = DIR$(Path$)            ' Get the first filename. IF TempName$ = &quot;&quot; THEN PRINT &quot;No file(s) found&quot; ELSE FileName$(Counter) = TempName$ ' Keep getting filenames until we Counter = Counter + 1          ' have NumFiles worth or we get DO                            ' them all. TempName$ = DIR$ IF TempName$ <> &quot;&quot; THEN FileName$(Counter) = TempName$ Counter = Counter + 1 LOOP WHILE TempName$ <> &quot;&quot; AND Counter <= NumFiles END IF IF FileName$(0) <> &quot;&quot; THEN   ' Display filenames if we received Counter = 0                ' any. DO   PRINT FileName$(Counter) IF FileName$(Counter) = &quot;&quot; THEN Finished = TRUE Counter = Counter + 1 LOOP WHILE Counter <= NumFiles AND NOT Finished END IF END

Example 2
' To try this example in VBDOS.EXE: ' 1. From the File menu, choose New Project. ' 2. Copy the code example to the Code window. ' 3. Press F5 to run the program. ' ' This example works in QuickBasic for MS-DOS, versions 2.0, 2.01, 3.0, ' 4.0, 4.0b, and 4.5; and Basic Compiler for MS-DOS and MS OS/2, ' versions 6.0 and 6.0b; and Basic PDS for MS-DOS and MS OS/2, ' versions 7.0 and 7.1.

nf = 200  ' Handles directory listing up to 200 lines. DIM buffer$(nf) INPUT &quot;Enter Search Path: &quot;, path$  ' Enter path such as c: SHELLSTRING$ = &quot;dir &quot; + path$ + &quot; >dirfile.dat&quot; SHELL SHELLSTRING$  ' SHELL to the MS-DOS DIRectory command. OPEN &quot;dirfile.dat&quot; FOR INPUT AS #1 pntr% = 0 WHILE NOT EOF(1) AND pntr% < nf pntr% = pntr% + 1 INPUT #1, buffer$(pntr%) ' Inputs one directory line at a time. PRINT buffer$(pntr%) WEND CLOSE #1 KILL &quot;dirfile.dat&quot; END

Example 3
' To try this example in VBDOS.EXE: ' 1. From the File menu, choose New Project. ' 2. Copy the code example to the Code window. ' 3. Press F5 to run the program.

' To run this program in the environment, you must invoke the ' environment with the /L switch to load the default Quick library: '   VBDOS.EXE /L          for Visual Basic 1.0 for MS-DOS

' Use the following include file for Visual Basic 1.0 for MS-DOS: REM $INCLUDE: 'VBDOS.BI' ' This examples works in QuickBasic for MS-DOS, versions 4.0, 4.0b, ' and 4.0; and Basic Compiler for MS-DOS and MS OS/2 (real mode only), ' versions 6.0 and 6.0b.

' Use the following include file for QuickBasic for MS-DOS: REM $INCLUDE: 'QB.BI'

TYPE FileFindBuf dos           AS STRING * 21 Attributes    AS STRING * 1 CreateTime    AS INTEGER AccessDate    AS INTEGER FileSize      AS LONG FileName      AS STRING * 13 END TYPE TYPE FileInfo FileName      AS STRING * 13 Size          AS STRING * 8 Seconds       AS STRING * 4 Minutes       AS STRING * 4 Hours         AS STRING * 4 Day           AS STRING * 4 Month         AS STRING * 4 Year          AS STRING * 5 END TYPE DIM BUFFER AS FileFindBuf DIM FileInfoBlock(100) AS FileInfo DECLARE SUB intbuf (BUFFER AS FileFindBuf) DECLARE SUB setdta (BUFFER AS FileFindBuf) DECLARE FUNCTION firstfm! (path$, fa%) DECLARE FUNCTION nextfm DECLARE SUB CalculateAssign (FileInfoBlock AS ANY, BUFFER AS ANY,_                            counter!) DECLARE SUB PrintDirList (FileInfoBlock AS ANY, i!) CLS : CALL setdta(BUFFER) INPUT &quot;Enter the files spec: &quot;; path$ fa% = 0 ' A value of 16 includes directory names. counter = 0 IF (firstfm(path$, fa%) = 0) THEN DO  counter = counter + 1 CalculateAssign FileInfoBlock, BUFFER, counter CALL setdta(BUFFER) LOOP WHILE (nextfm = 0) END IF

CLS FOR i = 1 TO counter PrintDirList FileInfoBlock, i NEXT i

END

SUB CalculateAssign (FileInfoBlock AS FileInfo, _                    BUFFER AS FileFindBuf, counter) FileInfoBlock(counter).FileName = BUFFER.FileName FileInfoBlock(counter).Size = STR$(BUFFER.FileSize) FileInfoBlock(counter).Seconds = STR$(BUFFER.CreateTime AND &H1F) FileInfoBlock(counter).Minutes = _ STR$((BUFFER.CreateTime AND &H7E0) \ 32) ' If BUFFER.CreateTime is negative add 64K to make unsigned integer: IF BUFFER.CreateTime < 0 THEN FileInfoBlock(counter).Hours = _ STR$(((BUFFER.CreateTime + 2 ^ 16) AND &HF800) \ 2048) ELSE FileInfoBlock(counter).Hours = _ STR$((BUFFER.CreateTime AND &HF800) \ 2048) END IF  FileInfoBlock(counter).Day = STR$(BUFFER.AccessDate AND &H1F) FileInfoBlock(counter).Month = _ STR$((BUFFER.AccessDate \ 32) AND &HF) FileInfoBlock(counter).Year = _ STR$((BUFFER.AccessDate \ 512) + 1980) END SUB

FUNCTION firstfm (path$, fa%) DIM inreg AS regtypeX, outreg AS regtypeX ' Use regtype for QuickBasic. inreg.ax = &H4E00 inreg.cx = fa% FileName$ = path$ + CHR$(0) inreg.dx = SADD(FileName$) inreg.ds = SSEG(FileName$) ' Use CALL INTERRUPT in QuickBasic for MS-DOS. CALL INTERRUPTX (&H21, inreg, outreg) firstfm = (outreg.ax AND &HF) END FUNCTION

SUB intbuf (BUFFER AS FileFindBuf) STATIC ' The first 20 bytes are reserved for MS-DOS and are unchanged. BUFFER.CreateTime = 0 BUFFER.Attributes = &quot; &quot; BUFFER.AccessDate = 0 BUFFER.FileSize = 0 BUFFER.FileName = STRING$(13, 32) END SUB

FUNCTION nextfm DIM inreg AS regtype, outreg AS regtype inreg.ax = &H4F00 CALL interrupt(&H21, inreg, outreg) nextfm = outreg.ax AND &HF END FUNCTION

SUB PrintDirList (FileInfoBlock AS FileInfo, i) PRINT FileInfoBlock(i).FileName; PRINT SPACE$(5); FileInfoBlock(i).Size; PRINT SPACE$(5); RTRIM$(LTRIM$(FileInfoBlock(i).Month)) + &quot;-&quot;; IF LEN(RTRIM$(LTRIM$(FileInfoBlock(i).Day))) = 1 THEN FileInfoBlock(i).Day = &quot;0&quot; + LTRIM$(FileInfoBlock(i).Day) END IF PRINT RTRIM$(LTRIM$(FileInfoBlock(i).Day)) + &quot;-&quot;; PRINT RTRIM$(LTRIM$(FileInfoBlock(i).Year)); IF VAL(FileInfoBlock(i).Hours) = 0 THEN FileInfoBlock(i).Hours = STR$(12) ' Change midnight from 0 to 12. END IF IF VAL(FileInfoBlock(i).Hours) > 12 THEN x% = VAL(FileInfoBlock(i).Hours) - 12 FileInfoBlock(i).Hours = STR$(x%) suffix$ = &quot;p&quot; ELSE suffix$ = &quot;a&quot; END IF IF VAL(FileInfoBlock(i).Hours) = 12 AND_ VAL(FileInfoBlock(i).Minutes) > 0 THEN suffix$ = &quot;p&quot; END IF IF LEN(RTRIM$(LTRIM$(FileInfoBlock(i).Hours))) = 1 THEN t% = 7 ELSE t% = 6 END IF PRINT SPACE$(t%); RTRIM$(LTRIM$(FileInfoBlock(i).Hours)) + &quot;:&quot;; IF LEN(RTRIM$(LTRIM$(FileInfoBlock(i).Minutes))) = 1 THEN FileInfoBlock(i).Minutes = &quot;0&quot; + LTRIM$(FileInfoBlock(i).Minutes) END IF PRINT RTRIM$(LTRIM$(FileInfoBlock(i).Minutes)); PRINT suffix$ END SUB

SUB setdta (BUFFER AS FileFindBuf) STATIC DIM inreg AS regtypex, outreg AS regtypex CALL intbuf(BUFFER) inreg.ax = &H1A00 inreg.ds = VARSEG(BUFFER) inreg.dx = VARPTR(BUFFER) CALL interruptx(&H21, inreg, outreg) END SUB

Additional query words: VBmsdos QuickBas BasicCom 1.00 2.00 3.00 4.00 4.00b 4.50 6.00 6.00b 7.00 7.10

Keywords: KB41447

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.