再将程序修改了一下,但又有了两个从没想到过的难题:
1.当用SET设置超过9个变量时怎么办?
2.当出现变量空间溢出时怎么办?
现在将程序分作了两个程序,一个主程序 CC.BAT, 一个密码子程序 password.bat,现在可以做到不允许用 Ctrl+C 来非法终止密码验证过程了!
密码子程序 password.bat
@echo off
rem 好像变量只能用9个,本程序中变量用到了10个,结果发现最后一个变量geiding2无法赋值而运行出错!使用了shift命令还是没用,如何解决?
shift
rem ------程序给定的初始密码 123456-------------
rem 密码可为任意位长度的数字,用户可更改。nul
if "%verify%"=="pass" goto end
goto start
:end
if exist pass.bat del pass.bat>nul
echo.
echo Run my BAT or enter windows ...
密码子程序 password.bat
@echo off
rem 可自定义密码的处理程序 password.bat
rem ------程序给定的初始密码 123456-------------
set geiding=123456
rem --------调用用户已设定的密码---------------
if exist c:\windows\msapps\keyfile.bat call c:\windows\msapps\keyfile.bat>nul
rem -----初始化设置-------
echo set verify=>pass.bat
set inputecho=Please input the password>nul
set option=quit>nul
set startinfo=press C>nul
goto input
:change
set passecho=
set password=
set inputecho=Input the OLD password>nul
set option=setkey1>nul
set startinfo=...>nul
rem --------密码验证---------------------------
:input
cls
echo Change password %startinfo%
for %%a in (1 2) do echo.
rem 将提示信息另显出来不要加在CHOICE循环后面,否则在DOS下运行时回闪很利害。
echo %inputecho% (clear-X OK-Y): %passecho%
choice /c:1234567890XYC /n
if errorlevel 13 goto change
if errorlevel 12 goto inputok
if errorlevel 11 goto clear
set passecho=%passecho%*
if errorlevel 10 set password=%password%0
rem 如果取值为0,则必须在下面的for循环前加上if not errorlevel 10,否则会出错!后同。
if not errorlevel 10 for %%n in (1 2 3 4 5 6 7 8 9) do if errorlevel %%n set password=%password%%%n
goto input
:inputok
cls
echo Change password %startinfo%
for %%a in (1 2) do echo.
echo %inputecho% (clear-X OK-Y): %passecho%
if == goto %option%
:error
for %%a in (1 2) do echo.
echo password error!!!
echo.
pause
:clear
set passecho=
set password=
goto input
rem --------密码修改---------------------------
:setkey1
set geiding1=
set setecho1=
:setting1
cls
echo setting password ...
for %%a in (1 2) do echo.
echo Input the OLD password (clear-X OK-Y): %passecho%
for %%a in (1 2) do echo.
echo Input the NEW password (clear-X OK-Y): %setecho1%
choice /c:1234567890XY /n
if errorlevel 12 goto setkey2
if errorlevel 11 goto setkey1
set setecho1=%setecho1%*
if errorlevel 10 set geiding1=%geiding1%0
if not errorlevel 10 for %%n in (1 2 3 4 5 6 7 8 9) do if errorlevel %%n set geiding1=%geiding1%%%n
goto setting1
:setkey2
rem 密码不能设为空,否则下次无法进入了。下同。
if "%geiding1%"=="" goto setting1
set geiding2=
set setecho2=
:setting2
cls
echo setting password ...
for %%a in (1 2) do echo.
echo Input the OLD password (clear-X OK-Y): %passecho%
for %%a in (1 2) do echo.
echo Input the NEW password (clear-X OK-Y): %setecho1%
for %%a in (1 2) do echo.
echo Again the NEW password (clear-X OK-Y): %setecho2%
choice /c:1234567890XY /n
if errorlevel 12 goto setok
if errorlevel 11 goto setkey2
set setecho2=%setecho2%*
if errorlevel 10 set geiding2=%geiding2%0
if not errorlevel 10 for %%m in (1 2 3 4 5 6 7 8 9) do if errorlevel %%m set geiding2=%geiding2%%%m
goto setting2
:setok
if "%geiding2%"=="" goto setting2
if "%geiding1%"=="%geiding2%" goto write
for %%a in (1 2) do echo.
rem 说两次设定的密码不一致怎么表达?我英语实在...
echo First and second out of line with the password !
echo.
pause
goto setkey1
:write
set geiding=%geiding2%
if not exist c:\windows\nul md c:\windows
if not exist c:\windows\msapps\nul md c:\windows\msapps
echo set geiding=%geiding%>c:\windows\msapps\keyfile.bat
:quit
echo set verify=pass>pass.bat
rem 还有一个问题,为什么为里直接用set verify=pass,返回到主程序后赋值不成功?非得要转借另一个子程序?
cls
Re zww3008:
可以看得出来,你真得很下功夫!对此我十分钦佩。我以前也如你一般,现在,杂事太多了。根据你的程序和问题作以下答复:
1,变量大小的问题。
不能不提醒你,你对环境变量的使用未免太奢侈了一些,连提示语句也用它来表示,是有些舍本逐末了。要知道对于编程者来说,一块公共数据区的使用,是应该慎之又慎的。我自己编过的程序,一般很少用过三个以上的变量,如果一定要用到较多变量的时候,一般都会用加上环境空间大小检测模块,以免出错。
2,变量空间的问题。
如果你无法缩减变量,那么只能扩大环境空间。方法除了你上面提到的之外,还可以使用
command /e:空间大小 /c 批处理命令 批处理模块 批处理参数
的方式,这就是用command调用批处理的另一好处了。
3,标记设定的问题。
你的 verify 变量无法之直接在外壳中判定,原因很简单。因为两层壳使用的不是同一块环境空间,dos中使用command创建新壳,会按照参数e重新分配一块环境变量空间,然后将母壳的全部变量复制到子壳中,而在回收壳时,并不会复制子壳的变量到母壳。
所以,我说的“标记”,在这里不是指环境变量,而是指文件。比如下面的例子:
echo > pass.bat (子壳中)
......
if exist pass.bat goto end (母壳中)
4,模块调用的问题。
我所说的“子程序”并非一定要是一个独立的文件,他可以是程序中的一个区段,使用的方法如下:
::In shell
if == goto input
......
command /e:2048 /c %0.bat $sub
......
::In subroutine
:input
......
:end
5,你的解决闪屏问题的方法,倒是很让我意外,我也是受益匪浅哪。
6,可以看出,随着程序功能的完善,程序复杂性的问题迅速突出,这个问题我已经在http://model.chinajewelry.net/dos/dosbbs/dispbbs.asp?boardid=12&id=8609讨论过,不再多说了。