我正在使用三个函数。一种是获取驱动器列表:
REM list the drives
:list_disk
ECHO List of drives
set n=0
for /f "skip=1 delims=" %%a in ('wmic logicaldisk get DeviceID^') do (
set nom[!n!]=%%a
set /A n+=1
)
set /A "N=%n%/2"
FOR /L %%i IN (0,1,%N%) DO (
echo !nom[%%i]!
echo/
)
EXIT /B 0第二种方法是建议用户选择在下一个函数中应该处理哪些驱动器:
REM choice of drives
:choix nom
echo Choice
FOR /L %%i IN (0,1,%N%) DO (
echo Do you want to raise the drive !nom[%%i]!
echo (y/n^) ?
SET c=n
SET /P c=
if !c!==y call :HASH i
)
EXIT /B 0最后一个文件使用数组的索引来处理所选驱动器:
REM fingerprinting
:HASH
ECHO Fingerprinting in progress ...
echo !nom[%%i]!
ECHO progam integration fingerprint :
EXIT /B 0问题是最后一个echo !nom[%%i]!不能像预期的那样工作。
为什么它不打印选择哪个驱动器?
发布于 2022-07-26 09:02:12
主要问题是将字符串i而不是循环变量i的值传递给子程序HASH,方法是使用if !c!==y call :HASH i而不是if !c!==y call :HASH %%i,并将循环循环变量的值引用到子程序执行上下文中根本不存在的echo !nom[%%i]!,而不是传递给echo !nom[%1]!的子程序的值。
但是这段代码还有其他一些问题,比如因为索引驱动器错误或使用set /p而忽略了最后一个驱动器,尽管在这里使用choice肯定会更好,因为它更安全、更可靠。
还建议在批处理文件中引用具有完全限定文件名的具有已知路径的可执行文件,这样可以加快批处理文件的执行速度,因为cmd.exe不需要使用环境变量PATH和PATHEXT搜索可执行文件,从而避免在执行批处理文件期间进行大量文件系统访问。
更好的代码是:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem list the drives
:list_disk
echo List of drives
echo/
set n=-1
for /F "tokens=2 delims==:" %%i in ('%SystemRoot%\System32\wbem\wmic.exe LOGICALDISK GET DeviceID /VALUE') do (
set /A n+=1
set nom[!n!]=%%i
)
for /L %%i IN (0,1,%n%) do echo !nom[%%i]!:
rem choice of drives
:choix nom
echo/
echo Choice
echo/
for /L %%i in (0,1,%n%) do (
%SystemRoot%\System32\choice.exe /C NY /N /M "Do you want to raise the drive !nom[%%i]!: (Y/N)?"
if errorlevel 2 call :HASH %%i
)
exit /B 0
rem fingerprinting
:HASH
echo/
echo Fingerprinting in progress for drive !nom[%1]!: ...
rem Call of the command to generate the fingerprint for drive !nom[%1]!
echo program integration fingerprint:
echo/
exit /B 0第一个 for 循环现在只将没有冒号的驱动器字母分配给带有name[x]的环境变量,这样x在0到n的范围内,例如,在wmic输出的四个驱动器上,0到3。
wmic选项/VALUE和for /F options tokens=2和delims==:的使用避免了for错误解析wmic的UTF-16小终端输出的问题。命令for将0D 00 0A 00 (utf-16le编码的回车+行提要)解释为错误的0D 0D 0A (回车+回车+行进给)。这种错误的Unicode文本解析并不重要,因为只将来自i输出的DeviceID=和:之间的驱动器字母分配给循环变量wmic。
因此,分配给n的处理行和创建的环境变量的数量是正确的,不再需要再除以2。n现在是用于定义带有驱动器号的环境变量的最后一个索引号。
选择的 for 循环现在使用选项命令提示用户选择Yes/No。命令行中的字母Y可以替换为法语版本的O,即使用/C NO和(O/N)。有关详细信息,请参阅我对如何阻止Windows命令解释器在不正确的用户输入上退出批处理文件执行?的回答
另一种使用mountvol.exe而不是wmic.exe的解决方案(从构建22572开始,在Windows11中不再可用):
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem list the drives
:list_disk
echo List of drives
echo/
set n=-1
for /F "delims=: " %%i in ('%SystemRoot%\System32\mountvol.exe ^| %SystemRoot%\System32\find.exe ":\" ^| %SystemRoot%\System32\sort.exe') do (
set /A n+=1
set nom[!n!]=%%i:
)
for /L %%i IN (0,1,%n%) do echo !nom[%%i]!
rem choice of drives
:choix nom
echo/
echo Choice
echo/
for /L %%i in (0,1,%n%) do (
%SystemRoot%\System32\choice.exe /C NY /N /M "Do you want to raise the drive !nom[%%i]! (Y/N)?"
if errorlevel 2 call :HASH %%i
)
exit /B 0
rem fingerprinting
:HASH
echo/
echo Fingerprinting in progress for drive !nom[%1]! ...
rem Call of the command to generate the fingerprint for drive !nom[%1]!
echo program integration fingerprint:
echo/
exit /B 0在这种情况下,环境变量是用驱动器号和冒号定义的,因为冒号已经在set nom[!n!]=%%i:上添加了。还可以使用delims=\而不是delims=:和set nom[!n!]=%%i来获得用驱动器号和冒号定义的环境变量。
另一种使用fsutil.exe获取带有冒号的驱动器以将它们分配给环境变量的解决方案是:
for /F "tokens=1*" %%i in ('%SystemRoot%\System32\fsutil.exe fsinfo drives') do for %%k in (%%j) do for /F "delims=\" %%l in ("%%k") do (
set /A n+=1
set nom[!n!]=%%l
)可以省略for /F "delims=\" %%l in ("%%k") do,并将set nom[!n!]=%%l改为set nom[!n!]=%%k以获得带有冒号的驱动器,并将反斜杠分配给环境变量,即C:\、D:\、.而不是C:,D: .
这个第三个解决方案的其他行(获取驱动器)与使用mountvol.exe的第二个解决方案相同。
注意:使用fsutil.exe的解决方案期望输出如下:
Drives: C:\ D:\ R:\这是英语Windows上的输出。如果有多个空格分隔字,从第一个输出驱动器到第一个输出驱动器,最后以:而不是Drives:结尾,最好在第一个for /F命令中使用"tokens=1* delims=:"而不是只使用"tokens=1*"来忽略fsutil.exe输出中左到第一个冒号的字符串,而不是左到第一个空格,并使用第二个for命令处理行的其余部分。
要了解所使用的命令及其工作方式,请打开一个命令提示符窗口,在那里执行以下命令,并非常仔细地读取为每个命令显示的所有帮助页。
call /?choice /?echo /?endlocal /? ...未显式使用,但由cmd.exe隐式运行。exit /?find /?for /?fsutil /?fsutil fsinfo /?mountvol /?rem /?set /?setlocal /?sort /?wmic /?wmic logicaldisk /?wmic logicaldisk get /?https://stackoverflow.com/questions/73119586
复制相似问题