Board logo

标题: [寻求完善]一个判断光驱的新办法 [打印本页]

作者: quya     时间: 2008-5-26 19:04    标题: [寻求完善]一个判断光驱的新办法
问题是这样引起的。

看见别人写了个判断 光盘的例子

for %%i in (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 if exist %%i\WIN51 set CDROM=%%i

上边的方法很简单, 但有个问题,就是当光驱中没有光盘的时候,会弹出错误信息,然后后边的命令就无法执行, 更糟糕的是, 如果有双光驱, 光盘在第2个光驱的时候, 根本就无法得到结果, 因为第一个光驱读不出, 第2个光驱无法检测。

于是我利用 Dready 这个小程序, 这个小程序用法是 Dready /w, 返回 errorlevel 0,1,2,255, 如果返回1, 表示是 Readonly, 也就是表示这个是光驱, 并且准备好了。

我改了下程序

for %%i in (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 Dready %%i &if errorlevel 1 echo %%i>>cdrom.txt

我的设想是先检测出可读的光驱到临时文件中,然后再次用 For 命令检测光驱中文件 WIN51, 第2步 很容易编, 问题就出在上边的第一步。

cdrom.txt 文件的结果不是我希望的, 因为errorlevel 的值一直是检测最后一个光驱的值, 我想这就是延迟变量的问题。

于是我在程序中 加入 setlocal ENABLEDELAYEDEXPANSION

并使用 !errorlevel! 代替 %errorlevel %, 但实际发现 !errorlevel!不是一个数值, 而是 !errorlevel!本身

最后我简单编了个 程序如下:

setlocal ENABLEDELAYEDEXPANSION
set test="No problem"
echo !test!

实际运行结果不是 No probelm, 而是 !test!, 这是怎么回事??

我照抄例子的时候是对的, 我自己编却错,而且也不是 !全角半角的问题,这点知识我还是有的。

我为了避免错误, 很多句子是拷贝的, 只是 set=xxx 的自己写, 可是就是错误, 我想不通了。

请大家帮帮我, 谢谢!

Last edited by quya on 2008-5-29 at 12:41 PM ]

作者: HAT     时间: 2008-5-26 19:10
把你的完整代码贴出来看看

作者: 26933062     时间: 2008-5-26 19:19
看看这个适合你不。

@echo off
set "var1=fsutil fsinfo drives"
set "var2=fsutil fsinfo drivetype"
for /f "skip=2 tokens=1 delims=:" %%a in ('%var1%^|more') do (
for /f "delims=" %%i in ('%var2% %%a: ^| find/i "cd-rom"') do call :loop "%%i"
)
pause&exit
:loop
set num=%~1
set num=%num:~0,1%
if exist %num%:\nul.ext (
echo.&echo 光盘是 %num% 盘 里面有光盘
) else (
echo.&echo 光盘是 %num% 盘 无光盘
)
goto :eof


Last edited by 26933062 on 2008-5-26 at 07:33 PM ]

作者: quya     时间: 2008-5-26 20:07
3楼的, 你的代码好神奇, 我看不懂, 但功能确实是我需要的。

你代码很复杂, 我想学也无从学起。

估计要你解释,即使你有耐心我也不一定懂。

我只想奢望地问你一下,如果按我思路编, 应该怎么编? 因为我知道我的代码。

谢谢你!!!!

作者: quya     时间: 2008-5-26 20:17
哈哈, 有点理解你的代码了, 因为 fsutil 居然是个命令。

而且 fsutil fsinfo drivetype [drives] 会显示 “CD-ROM”,“固定驱动器” 之类的东西。

太感谢了, 学了一招!

作者: quya     时间: 2008-5-26 20:37
好像还是不行,我在第一个光驱中放盘, 第2个光驱无盘。成功显示信息

第2次倒过来,第2个光驱放,第一个光驱不放,就出现弹出信息。

之后又恢复到第1种情况, 还是弹出。

重复N次, 再没成功过。

不解中.......

作者: bat-zw     时间: 2008-5-26 21:22    标题: 楼主试试这个:

@echo off
for /f "delims=驱动器:\ " %%i in ('fsutil fsinfo drives^|more') do fsutil fsinfo drivetype %%i: |findstr "CD-ROM">nul&&call :lp %%i
pause>nul&goto :eof
:lp
if exist %1:\autorun.inf (
echo 光驱%1:中有盘。
) else(
echo 光驱%1:中无盘。
)


Last edited by zw19750516 on 2008-5-26 at 10:14 PM ]

作者: 26933062     时间: 2008-5-26 22:12
:这样呢


@echo off
set "var1=fsutil fsinfo drives"
set "var2=fsutil fsinfo drivetype"
for /f "skip=2 tokens=1 delims=:" %%a in ('%var1%^|more') do (
for /f "delims=" %%i in ('%var2% %%a: ^| find/i "cd-rom"') do call :loop "%%i"
)
echo.&pause&exit
:loop
set num=%~1&set "str="
set "num=%num:~0,1%"
dir %num%: >nul 2>nul
if %ERRORLEVEL% equ 0 (echo.&echo 光盘是 %num% 盘 里面有光盘) else (
echo.&echo 光盘是 %num% 盘 无光盘
)
goto :eof


Last edited by 26933062 on 2008-5-26 at 10:16 PM ]

作者: quya     时间: 2008-5-26 22:27
7 楼的程序有错误
8楼的快接近完美了, 可是有点小错。运行结果如下:


光盘是 H 盘 无光盘

光盘是 I 盘 里面有光盘

请按任意键继续. . .

光盘是 ~0,1 盘 无光盘

能把最后一个无效信息去掉就更好,我也正在研究,何处会发生这个小错。

再次感谢!

8楼构思巧妙, 用dir 无光盘光驱只会显示“设备未就绪”(不会弹错误信息), 比那个判断 if exist 文件的句子要强太多!!! 晕! 为什么大家只想到了后者?

Last edited by quya on 2008-5-26 at 10:32 PM ]

作者: 26933062     时间: 2008-5-26 22:33
这个错误信息是在 请按任意键继续. . . 之后出现的吗?
如果是,你确定你是完全复制8楼的代码的吗?那后面是有exit的啊!!~~~

作者: 26933062     时间: 2008-5-26 22:43
整理了一下

@echo off&setlocal EnableDelayedExpansion
set "var1=fsutil fsinfo drives"
set "var2=fsutil fsinfo drivetype"
for /f "skip=2 tokens=1 delims=:" %%a in ('%var1%^|more') do (
%var2% %%a: | find/i "cd-rom">nul&&(
set "str=%%a"
set "str=!str:~0,1!"
dir !str!: >nul 2>nul
if !ERRORLEVEL! equ 0 (echo.&echo 光盘是 !str! 盘 里面有光盘) else (
echo.&echo 光盘是 !str! 盘 无光盘
)))
echo.&pause&exit

作者: quya     时间: 2008-5-26 22:57
我因为要调试, 而且以后要用在批处理,并且还要赋值,所以不能 EXIT

dir >nul 2>nul 那个 2>nul 什么意思? 不写这个, 有信息回显。 我还试了 3>nul , 结果似乎进入一个shell了,只好 EXIT 退出,昏! 从来没看到这样的用法, “26933062” 是强人, 不佩服不行。

作者: 26933062     时间: 2008-5-26 22:59
不能用exit就改为 goto 目标标签,
否则,再显示完后继续运行:loop下面的代码当然就会出现你9楼说的错误情况了。
或者用11楼的就可以了。

作者: quya     时间: 2008-5-26 23:13
谢谢 26933062, 我之所以要这样一个批处理, 因为我想制作一个 多合一 的XP SP3 安装盘。

目前大多数的多合一盘是有菜单的, 我想做一个无菜单的, 可自动监测机器是否是 OEM机器,如果是,则安装OEM相应版本 (如果光盘上有相应文件), 否则装 VOL版的。

无菜单的好处是可以提高光盘启动的兼容性。

我差不多已经完成了, 其实现在要的程序在实际安装系统的中途是不会把光盘取出来的(但依旧存在双光驱的问题), 但我想可能有人会把我的部分程序拷到硬盘执行,那么就会出现错误信息,我觉得非常不爽, 这才苦思冥想要解决。

今天真是学到东西了!

在实现这个设想的过程中,我用到了一些dos命令,都是用的很笨的命令,但实现的功能在我看起来很复杂。 26933062, 你很强, 我的乱七八糟代码如果你看到恐怕会笑死。

Last edited by quya on 2008-5-26 at 11:16 PM ]

作者: 26933062     时间: 2008-5-26 23:33    标题: 回复 14 楼
别客气,大家相互帮助的同时,其实自己也在进步。
你夸我夸的过了,这个论坛里,高手如云,我岂敢妄谈“强”字。
好好看看这里的老帖,你会知道什么才是真正的 强 !

作者: quya     时间: 2008-5-28 22:13
还有点问题请教。

据说 fsutil 这个命令只能限制成管理员用, 而且XP Pro版才能用。

dir [drive] >nul 2>nul 这个太有用了。

但是否我们只能回到 for %%i in (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 if exist %%i\WIN51 set CDROM=%%i

这个老路上去? 这条老路也有缺陷,就是要判断特定文件, 有无更好办法呢?

作者: quya     时间: 2008-5-28 23:08
根据26933062思路, 我做了个

@echo off&setlocal EnableDelayedExpansion
for /f "usebackq skip=1 tokens=2 delims==" %%a in (`findcd /s`) do (
set "str=%%a"
set "str=!str:~0,1!"
dir !str!: >nul 2>nul
chcp 936>nul
if !ERRORLEVEL! equ 0 (echo.&echo 光盘是 !str! 盘 里面有光盘) else (
echo.&echo 光盘是 !str! 盘 无光盘
))
echo.&pause&exit


说明: findcd.exe 是第三方程序,只有3.11K

这个程序 findcd 如果加 /s 参数则列出多光盘,结果如下例:

CDROM=2
CDROM1=H:
CDROM2=I:

在老DOS下 会赋值给上述变量, 省却许多麻烦, 但在XP下却不能!而且会改变 codepage, 所以我加了条 CHCP 936。

实际运行结果如下:

光盘是 2 盘 里面有光盘

光盘是 H 盘 里面有光盘

光盘是 I 盘 里面有光盘

请按任意键继续. . .


怎么会多了一行,似乎 Skip=1 没用处,不解。

怎么没办法插入附件? 我想附上 findcd的程序。这儿下载

Last edited by quya on 2008-5-28 at 11:29 PM ]

作者: WANKOILZ     时间: 2008-5-29 19:34
%var1%^|more
%var2% %%a:
11楼这招看起来很整洁啊!

Last edited by WANKOILZ on 2008-5-29 at 07:38 PM ]