Tom's Guide | Tom's Hardware | Tom's Games
![]() |
![]() |
![]() |
I am currently tinkering with a piece of code which pulls up the drives connected to my pc. this works fine however what I would like ideally is a number list of each drive which is what i'm currently trying to work out.
----------------
@echo off & setlocal enableextensions
for %%d in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do fsutil fsinfo drivetype %%d: | find /v "No such Root Directory"
::endlocal & goto :EOF
pause
----------------
eg - it current displays:
C: - Fixed Drive
D: - CD-ROM Drive
F: - CD-ROM DriveI would like:
1. C: - Fixed Drive
2. D: - CD-ROM Drive
3. F: - CD-ROM DrivePlease select a drive from the list:
Is this possible?

I knocked this up pretty quickly so forgive me if there are any mistakes:
@ECHO OFF
if [%1] neq [] goto list
set cnt=1
SETLOCAL ENABLEDELAYEDEXPANSION
for /f "delims=" %%a in ('call "%~f0" call^|find /n /v "No such Root Directory"') do set var!cnt!=%%a&&set /a cnt+=1
set /a cnt-=1
set svr=!cnt!
for /l %%h in (%cnt%,-1,1) do (
set var%%h=!var%%h:]=. !
set var%%h=!var%%h:[=!
)
for /l %%i in (1,1,%svr%) do echo !var%%i!
pause
goto :eof
:list
@for %%d in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) do (
fsutil fsinfo drivetype %%d:
)

Thanks for replying. Thats the sort of thing I want except the numbering of the drive letters don't seem to be correct. I get this:
3. C: - Fixed Drive
4. D: - CD-ROM Drive
6. F: - CD-ROM DriveI think the number is corresponding to the letter of the alphabet so if there was a drive Z, it would have 26 next to it. If possible, can I get the above to be 1,2,3?
Also, if possible, could I have the option of choosing a drive letter.
For example, I choose option 1 and C: would be saved as a variable?

[Edit: Small optimisation]
Ok I found some more time(well quite a bit) a made some changes. It no longer needs to call itself so it can be inserted into another script without disruption. It's a bit long, most of it is either house keeping or ensuring a valid option is chosen.
@echo off
set cnt=
set errmsg=echo invalid number - select again^&^&goto select
setlocal enabledelayedexpansion
for /f "delims=" %%d in ('fsutil fsinfo drives^|find ":"') do (
set tmp=%%d&&set tmp=!tmp:\=!&&set tmp=!tmp:Drives: =!
for /f "delims=" %%e in ('fsutil fsinfo drivetype !tmp!') do (
set /a cnt+=1&&echo !cnt!. %%e&&set ___var___!cnt!=%%e
)
)
:select
set drv=&&set err=&&set test=
set /p drv=please select your drive.
if not defined drv goto select
if "%drv:~0,1%"=="0" %errmsg%
for /f %%b in ('set /a %drv%*2 2^>^&1 1^>nul') do set err=%%b
if defined err %errmsg%
if %drv% gtr %cnt% %errmsg%
set /a test=%drv%*2>nul
if %test%==0 %errmsg%
set str=!___var___%drv%!
for /f %%c in ("%str%") do set drv=%%c
set cnt=&&set err=&&set test=&&set errmsg=
for /l %%g in (1,1,%cnt%) do set var%%g=
setlocal disabledelayedexpansion
echo the drive you selected is %drv%
pause

thanks for the reply. I have come to realise that this may be a long process for what I need (making a batch file to backup data).
After choosing the drive, they would then have to locate the folders etc each time they use the batch file and I guess theres no quick way around that?
I am currently using your code for the user to choose a backup drive (since when usb drives are sometimes plugged in dont always have the same letter). However, I now have 2 problems:
1. The list shows all drives.
2. usb drives appear as 'Removable Drive' and the user will not be able to differentiate between the 2. It would be better if the actual name of the disk was used as it appears in my computer ie. USB Drive A, USB Drive B.Is all this possible?

If your after the volume label, it should be easy. If you want the actual name of the disk(ie Kingston data traveller 2.0) it seems to become much more difficult. The only place I could find this data was in the registry. I'm not sure if these keys even point to which drive letter it is assigned.
Can anyone else jump in with some info and/or a solution?

Can anyone confirm that the reg binary data for usbflash drives is 160 hex bytes long.
HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices
If anyone is interested this hex data seems to contain the parentidprefix for HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\<flash name>\<flash serial????>
Can any one confirm if I am correct any info??

If there is no problem for you to use TCC/LE, (the free cmd.exe replacement from jpsoft), this is a cakewalk. %@label[c:] returns you c drive's label. Also, it has an internal variable called %_drives which has all the drives listed in it. This is how it looks in TCC/LE,
15:38:32 C:\audios\wwget>echo %@label[C:]
OS
15:44:53 C:\audios\wwget>echo %_drives
C: D: E: F: G: Z:(I have no affiliations with jpsoft. I just happens to be a one happy user of their software).
--
Holla.

Dimension said:
does this mean the computer i run the file on has to have that exe on it?
Yes. Of course. You need to have this on the computer where you will be running the script.
Not on those other computers which you are going to map as s: t: z: etc.
--
Holla.

[edit: Variable cleanup]
I've written a script, it works on my one windows xp machine with my one usb flash drive. It will probably have problems on different pc's. I have JUST written this and it is still incomplete, I have not attempted ANY cleanup for now it is "as is" and only attempts to find usb flash drives.
Please change <tab> in the script to an actual tab bearing in mind in is followed by space. The forums here convert tabs to spaces so it needs to be done.....
What it really needs is a pro's eye...
@echo off
set hexval=""................................ !"#$.&...*+,-./0123456789:;.=.?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]._`abcdefghijklmnopqrstuvwxyz{.}~.................................................................................................................................""
SETLOCAL ENABLEDELAYEDEXPANSION
set dcnt=
for /f "delims=" %%a in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR^|find "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\"') do (
for /f "delims=" %%b in ('reg query "%%a"^|find /i "%%a\"') do (
set /a dcnt+=1
for /f "tokens=1,2*" %%c in ('reg query "%%b"^|findstr /i "ParentIdPrefix FriendlyName"') do (
if /i "%%c"=="ParentIdPrefix" (set id!dcnt!="%%e") else set fname!dcnt!="%%e"
)
)
)
set lcnt=
for /f "tokens=2,4 delims=\<tab> " %%g in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices^|find ":"') do (
set /a lcnt+=1
set drvltt!lcnt!=%%g
set drvdat!lcnt!=%%h
)
for /l %%i in (1,1,!lcnt!) do (
set nn=%%i
set tdat=
call :delin
)goto cnvrt
:delin
if not defined drvdat%nn% set drvdat%nn%=%tdat:~1%&&goto :eof
set tdat=%tdat%¼!drvdat%nn%:~0,2!
set drvdat%nn%=!drvdat%nn%:~2!
goto delin:cnvrt
set hexval=!hexval:~2,-2!
set svr=!hexval!
for /l %%j in (1,1,!lcnt!) do (
set drvdat%%j=!drvdat%%j:00¼=!
set drvdat%%j=!drvdat%%j:¼00=!
set nn=%%j
set hexval=!svr!
for %%k in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do (
for %%l in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do (
set byte=%%k%%l
call :chge
)
)
)
for /l %%m in (1,1,!lcnt!) do set drvdat%%m=!drvdat%%m:¼=!
goto check:chge
set thex=!byte!=!hexval:~0,1!
set thex="!thex:&=^&!"
set thex=!thex:~1,-1!
set drvdat%nn%=!drvdat%nn%:%thex%!
set hexval=!hexval:~1!
goto :eof:check
set fcnt=
for /l %%n in (1,1,!dcnt!) do (
for /l %%o in (1,1,!lcnt!) do (
echo "!drvdat%%o!"|find !id%%n!>nul
if not errorlevel 1 (
dir !drvltt%%o!\>nul 2^>^&1
if not errorlevel 1 (
set /a fcnt+=1
set output!fcnt!=!drvltt%%o! !fname%%n!
)
)
)
)
if not defined fcnt echo no valid drive found&&pause&&goto :eof
set /a fcnt+=1
set output!fcnt!=Exit
:loop
for /l %%p in (1,1,!fcnt!) do echo %%p. !output%%p!
set /p dest=Please select a flash drive:
for /l %%p in (1,1,!fcnt!) do if "%%p"=="%dest%" goto finish
echo invalid choice
goto loop
:finish
if not "!output%dest%:~1,1!"==":" pause&&goto :eof
set dest=!output%dest%:~0,2!
endlocal & set dest=%dest%
set hexval=
echo You selected drive %dest%
pause

thanks for that. is it possible that i could have: if they choose a flash drive execute a certain statement, otherwise do something else?
i didnt think there would be so much code for all this!
i only have a simple script that asks if you would like to backup once a week!

Change the below line to either a goto or your commands if they choose "exit". Change "pause&&goto :eof" to "goto yourlabel" or "your command&&goto whereever" If they don't choose exit the program flow goes to the very end of the batch.
if not "!output%dest%:~1,1!"==":" pause&&goto :eofDoes the batch work fine for you?
I haven't done any clean up and expect a few bugs to pop up.

its close to what i want. i get the following:
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
FIND: Parameter format not correct
1. E: "USB DISK 2.0 USB Device"
2. Exit
Please select a flash drive:
i had a look at your code. im not the best batch file programmer and dont understand alot of it but i did notice the reference to the registry which is where it seems your pulling the devices from. i browsed to that registry location on my pc and there is all the usb devices ever connected to this pc. i guess this is why it says "Parameter format not correct" because its looking for a device thats not there?
-----------
I will first make an option which says: What would you like to backup to?1. Physical Hard Disk
2. Removable USB Diskthen they will choose. if they choose 1, all the hard disks should be shown and the user can choose which to use. if they choose 2, all usb disks are shown. does this make sense?

I think the problem was the dcnt counter was going up even if the parsed key didn't contain the data required, or all there of. I think this may have caused some of !id%dcnt%! variables to contain no data and thus the find command didn't have "quotes", which are part of the variable.
Try the modified version below(Don't forget to change <tab> to a tab).
As for selecting the hard drive you may want to use another method to that below, like the fsinfo method, as the whole operation becomes much more complicated with hard drives because of partitions, raid, scsi and other factors.
When selecting usb or hard disk you could call :labels or independent batches to make it easier to separate the components, especially since you only want a drive letter returned.
@echo off
set hexval=""................................ !"#$.&...*+,-./0123456789:;.=.?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]._`abcdefghijklmnopqrstuvwxyz{.}~.................................................................................................................................""
SETLOCAL ENABLEDELAYEDEXPANSION
set dcnt=
for /f "delims=" %%a in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR^|find "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\USBSTOR\"') do (
for /f "delims=" %%b in ('reg query "%%a"^|find /i "%%a\"') do (
set /a dcnt+=1
set chk=
for /f "tokens=1,2*" %%c in ('reg query "%%b"^|findstr /i "ParentIdPrefix FriendlyName"^|^|echo ifef') do (
if /i "%%c"=="ParentIdPrefix" set id!dcnt!="%%e"&&set /a chk+=1
if /i "%%c"=="FriendlyName" set fname!dcnt!="%%e"&&set /a chk+=1
)
if !chk! lss 2 set /a dcnt-=1
)
)
set lcnt=
for /f "tokens=2,4 delims=\<tab> " %%g in ('reg query HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices^|find ":"') do (
set /a lcnt+=1
set drvltt!lcnt!=%%g
set drvdat!lcnt!=%%h
)
for /l %%i in (1,1,!lcnt!) do (
set nn=%%i
set tdat=
call :delin
)goto cnvrt
:delin
if not defined drvdat%nn% set drvdat%nn%=%tdat:~1%&&goto :eof
set tdat=%tdat%¼!drvdat%nn%:~0,2!
set drvdat%nn%=!drvdat%nn%:~2!
goto delin:cnvrt
set hexval=!hexval:~2,-2!
set svr=!hexval!
for /l %%j in (1,1,!lcnt!) do (
set drvdat%%j=!drvdat%%j:00¼=!
set drvdat%%j=!drvdat%%j:¼00=!
set nn=%%j
set hexval=!svr!
for %%k in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do (
for %%l in (0 1 2 3 4 5 6 7 8 9 a b c d e f) do (
set byte=%%k%%l
call :chge
)
)
)
for /l %%m in (1,1,!lcnt!) do set drvdat%%m=!drvdat%%m:¼=!
goto check:chge
set thex=!byte!=!hexval:~0,1!
set thex="!thex:&=^&!"
set thex=!thex:~1,-1!
set drvdat%nn%=!drvdat%nn%:%thex%!
set hexval=!hexval:~1!
goto :eof:check
set fcnt=
for /l %%n in (1,1,!dcnt!) do (
for /l %%o in (1,1,!lcnt!) do (
echo "!drvdat%%o!"|find !id%%n!>nul
if not errorlevel 1 (
dir !drvltt%%o!\>nul 2^>^&1
if not errorlevel 1 (
set /a fcnt+=1
set output!fcnt!=!drvltt%%o! !fname%%n!
)
)
)
)
if not defined fcnt echo no valid drive found&&pause&&goto :eof
set /a fcnt+=1
set output!fcnt!=Exit
:loop
for /l %%p in (1,1,!fcnt!) do echo %%p. !output%%p!
set /p dest=Please select a flash drive:
for /l %%p in (1,1,!fcnt!) do if "%%p"=="%dest%" goto finish
echo invalid choice
goto loop
:finish
if not "!output%dest%:~1,1!"==":" pause&&goto :eof
set dest=!output%dest%:~0,2!
endlocal & set dest=%dest%
set hexval=
echo You selected drive %dest%
pause

![]() |
![]() |
![]() |

This post is quite old and has been locked from receiving new replies. Please create a new posting instead.
| Ads by Google |