|
walu
高级用户
积分 916
发帖 201
注册 2003-5-4
状态 离线
|
『楼 主』:
可自定义密码的密码程序(批处理)[转帖]
(注:此贴转自DOS之家的周文伟朋友,希望这里的高手能解决“该程序不能用bat2com制作成COM程序,制作后不支持%,不知哪位有什么解决办法?”这个问题)
可自定义密码的密码程序(批处理)
@echo off
rem ### 可自定义密码的密码程序 ###
rem
rem 作者:周文伟 zww3008@sina.com
rem
rem 作用:1.可加载在WINDOWS 98中的Autoexec.bat中作为另类开机密码(但需将提示信息改为英文,开机时启动的Autoexec.bat是不支持中文显示的),可唬一下一些菜鸟级的用户。
rem 2.可加载到你的批处理程序前,作为你的BAT程序的“壳”。
rem
rem 说明:1.该程序不能用bat2com制作成COM程序,制作后不支持%,不知哪位有什么解决办法?
rem 3.密码为4位长度的数字,如需增长,可增加相应程序段即可。
rem 4.程序采用常用的DOS命令,没有附加工具,可在各种windows版本中运行,兼容性好。
rem 2.程序中choice命令下的if errorlevel项有严格的排序,不能颠倒,读者自体味。
rem 3.哪位有更好的建议,欢迎交流学习:周文伟zww3008@sina.com
rem
rem ------程序给定的初始密码 3210-------------
rem 密码为 4 位长度的数字,初始为3210,用户可更改。
set key1=3>nul
set key2=2>nul
set key3=1>nul
set key4=10>nul
rem --------调用用户已设定的密码---------------
if exist c:\windows\MSAPPS\keyfile.bat call c:\windows\MsApps\keyfile.bat>nul
rem -----初始化设置-------
if %key1%==1 set key1d=2>nul
if %key1%==2 set key1d=3>nul
if %key1%==3 set key1d=4>nul
if %key1%==4 set key1d=5>nul
if %key1%==5 set key1d=6>nul
if %key1%==6 set key1d=7>nul
if %key1%==7 set key1d=8>nul
if %key1%==8 set key1d=9>nul
if %key1%==9 set key1d=10>nul
if %key1%==10 set key1d=11>nul
if %key2%==1 set key2d=2>nul
if %key2%==2 set key2d=3>nul
if %key2%==3 set key2d=4>nul
if %key2%==4 set key2d=5>nul
if %key2%==5 set key2d=6>nul
if %key2%==6 set key2d=7>nul
if %key2%==7 set key2d=8>nul
if %key2%==8 set key2d=9>nul
if %key2%==9 set key2d=10>nul
if %key2%==10 set key2d=11>nul
if %key3%==1 set key3d=2>nul
if %key3%==2 set key3d=3>nul
if %key3%==3 set key3d=4>nul
if %key3%==4 set key3d=5>nul
if %key3%==5 set key3d=6>nul
if %key3%==6 set key3d=7>nul
if %key3%==7 set key3d=8>nul
if %key3%==8 set key3d=9>nul
if %key3%==9 set key3d=10>nul
if %key3%==10 set key3d=11>nul
if %key4%==1 set key4d=2>nul
if %key4%==2 set key4d=3>nul
if %key4%==3 set key4d=4>nul
if %key4%==4 set key4d=5>nul
if %key4%==5 set key4d=6>nul
if %key4%==6 set key4d=7>nul
if %key4%==7 set key4d=8>nul
if %key4%==8 set key4d=9>nul
if %key4%==9 set key4d=10>nul
if %key4%==10 set key4d=11>nul
set startinfo=(修改密码按X键)
set chkinfo=
set opt=end
goto 1p
:needchk
set startinfo=
set chkinfo=4位旧
set opt=ch1
:1p
cls
echo.
echo.
choice /c:1234567890nX /n 请输入%chkinfo%密码%startinfo%:
if errorlevel 12 goto needchk
if errorlevel %key1d% goto err1
if errorlevel %key1% goto 2p
goto err1
:2p
cls
echo.
echo.
choice /c:1234567890n /n 请输入%chkinfo%密码:*
if errorlevel %key2d% goto err2
if errorlevel %key2% goto 3p
goto err2
:3p
cls
echo.
echo.
choice /c:1234567890n /n 请输入%chkinfo%密码:**
if errorlevel %key3d% goto err3
if errorlevel %key3% goto 4p
goto err3
:4p
cls
echo.
echo.
choice /c:1234567890n /n 请输入%chkinfo%密码:***
if errorlevel %key4d% goto err4
if errorlevel %key4% goto ok
goto err4
:err1
cls
echo.
echo.
choice /c:1234567890n /n 请输入%chkinfo%密码:*
:err2
cls
echo.
echo.
choice /c:1234567890n /n 请输入%chkinfo%密码:**
:err3
cls
echo.
echo.
choice /c:1234567890n /n 请输入%chkinfo%密码:***
:err4
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo key error!!!
echo.
pause
goto 1p
k
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo ---= OK! OK! OK! OK! =--
echo.
pause
goto %opt%
:ch1
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo.
choice /c:1234567890x /n 请输入4位新密码(按X重新输入):
if errorlevel 1 set key1=1
if errorlevel 2 set key1=2
if errorlevel 3 set key1=3
if errorlevel 4 set key1=4
if errorlevel 5 set key1=5
if errorlevel 6 set key1=6
if errorlevel 7 set key1=7
if errorlevel 8 set key1=8
if errorlevel 9 set key1=9
if errorlevel 10 set key1=0
if errorlevel 11 goto ch1
:ch2
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo.
choice /c:1234567890x /n 请输入4位新密码(按X重新输入):%key1%
if errorlevel 1 set key2=1
if errorlevel 2 set key2=2
if errorlevel 3 set key2=3
if errorlevel 4 set key2=4
if errorlevel 5 set key2=5
if errorlevel 6 set key2=6
if errorlevel 7 set key2=7
if errorlevel 8 set key2=8
if errorlevel 9 set key2=9
if errorlevel 10 set key2=0
if errorlevel 11 goto ch1
:ch3
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo.
choice /c:1234567890x /n 请输入4位新密码(按X重新输入):%key1%%key2%
if errorlevel 1 set key3=1
if errorlevel 2 set key3=2
if errorlevel 3 set key3=3
if errorlevel 4 set key3=4
if errorlevel 5 set key3=5
if errorlevel 6 set key3=6
if errorlevel 7 set key3=7
if errorlevel 8 set key3=8
if errorlevel 9 set key3=9
if errorlevel 10 set key3=0
if errorlevel 11 goto ch1
:ch4
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo.
choice /c:1234567890x /n 请输入4位新密码(按X重新输入):%key1%%key2%%key3%
if errorlevel 1 set key4=1
if errorlevel 2 set key4=2
if errorlevel 3 set key4=3
if errorlevel 4 set key4=4
if errorlevel 5 set key4=5
if errorlevel 6 set key4=6
if errorlevel 7 set key4=7
if errorlevel 8 set key4=8
if errorlevel 9 set key4=9
if errorlevel 10 set key4=0
if errorlevel 11 goto ch1
cls
echo.
echo.
echo 请输入%chkinfo%密码:****
echo.
echo.
echo 请输入4位新密码(按X重新输入):%key1%%key2%%key3%%key4%
echo.
if not exist c:\windows\nul md c:\windows
if not exist c:\windows\msapps\nul md c:\windows\msapps
echo @echo off>c:\windows\msapps\keyfile.bat
if %key1%==0 set key1=10
if %key2%==0 set key2=10
if %key3%==0 set key3=10
if %key4%==0 set key4=10
echo set key1=%key1%>>c:\windows\msapps\keyfile.bat
echo set key2=%key2%>>c:\windows\msapps\keyfile.bat
echo set key3=%key3%>>c:\windows\msapps\keyfile.bat
echo set key4=%key4%>>c:\windows\msapps\keyfile.bat
echo.
echo OK! 密码修改成功!请记住新密码。
echo.
echo.
echo 按任意键继续......
pause >nul
:end
cls
|
|
2004-1-6 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
2 楼』:
Re 周文伟朋友&walu:
程序的思路不错,只是重复性代码过多,一个四位数密码编到如此长度,未免太铺张了。倒是有助于对程序的理解
善于利用循环和判断才是解决问题的关键,在这方面已经有很成功的例子,现在还没时间去整理,在这只给一段关键代码:
:input
choice /c:1234567890q /n Please input the password: %passecho%
if errorlevel 11 goto quit
set passecho=%passecho%*
if errorlevel 10 set password=%password%0
for %%n in (1;2;3;4;5;6;7;8;9) do if errorlevel %%n set password=%password%%%n
if [%password%]==[1234] goto quit
goto input
[此贴子已经被作者于2004-1-9 9:11:32编辑过]
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-1-9 00:00 |
|
|
ZWW3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
3 楼』:
楼上的方法相当不错!我也想到了要用循环,可是不知道怎样下手,现在我按照您的方法改了一下,还有几个问题,希望能得到解答。
------------------------------------------------------------------
@echo off
rem ------程序给定的初始密码 123456-------------
rem 密码可为任意位长度的数字,用户可更改。
set geiding=123456
set leangh=6
rem --------调用用户已设定的密码---------------
if exist c:\windows\msapps\keyfile.bat call c:\windows\msapps\keyfile.bat>nul
rem -----初始化设置-------
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=setkey>nul
set startinfo=...>nul
rem --------密码验证---------------------------
:input
cls
echo Change password %startinfo%
for %%a in (1 2) do echo.
choice /c:1234567890XC /n %inputecho% (clear-X): %passecho%
if errorlevel 12 goto change
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
if [%password%]==[%geiding%] goto %option%
rem
if [%times%]==[%leangh%] goto error
goto input
:error
echo password error!!!
echo.
pause
:clear
set passecho=
set password=
goto input
rem --------密码修改---------------------------
:setkey
set geiding=
set leangh=
:setting
cls
echo setting password ...
for %%a in (1 2) do echo.
echo Input the OLD password (clear-X): %passecho%
for %%a in (1 2) do echo.
choice /c:1234567890XY /n Input the NEW password (clear-X OK-Y):%geiding%
if errorlevel 12 goto ok
if errorlevel 11 goto clearset
if errorlevel 10 set geiding=%geiding%0
if not errorlevel 10 for %%n in (1 2 3 4 5 6 7 8 9) do if errorlevel %%n set geiding=%geiding%%%n
goto setting
:clearset
set geiding=
goto setting
k
rem 密码不能设为空,否则下次无法进入了。
if "%geiding%"=="" goto setting
rem
cls
echo setting password ...
for %%a in (1 2) do echo.
echo The NEW password (clear-X OK-Y):%geiding%
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
echo set leangh=?>>c:\windows\msapps\keyfile.bat
for %%a in (1 2) do echo.
echo 密码设定完毕!请记住新密码!
for %%a in (1 2) do echo.
pause
:quit
cls
|
|
2004-1-9 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
4 楼』:
Re ZWW3008:
总体来说,你做得很不错。不过我只看了原码,没来得及测试。只就你的几个问题做以下答复,希望对你有所帮助。
如果取值为0,则必须在下面的for循环前加上if not errorlevel 10,否则会出错!后同。有谁能解悉一下?
--------------
因为if errorlevel的判断不是等于,而是大于等于。因为数字0是第十个选项字符,它大于9,所以循环中会将它多赋一个数字9。
--------------
限制密码长度一定需要记录次数吗?而且你保存密码长度的想法有欠妥当,密码最大长度应该是一个常数,而并非是正确密码的长度,否则很容易被人从长度猜测出密码的。给你另一个思路吧。
可以设置一个变量 passfull,其值为最大长度的遮盖字符,然后在循环中将它与 passecho 比较。例:
set passfull=******
...
if [%passecho%]==[%passfull%] goto full
另外,批处理有天生的缺陷,即可以被用户ctrl+c中断,做为口令登陆程序,应该需要考虑这方面的预防措施。现在时间有点紧,给你提一下大体思路,把口令判断的子程序做为登陆程序的一个子程序调用,也就是给他加一层壳,然后在壳内正确输入处理中做一个变量标记,在壳外判断是否存在这个标记,以此防止用户的非法脱壳。
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-1-9 00:00 |
|
|
zww3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
5 楼』:
感谢willsort。 上面的程序我自己测试过运行还是正常。
Quote: | 因为if errorlevel的判断不是等于,而是大于等于。因为数字0是第十个选项字符,它大于9,所以循环中会将它多赋一个数字9。 |
|
我没上过高等学校也从没有正规学习过电脑,也没学过编程,只是自己酷爱玩电脑自然少不了与DOS打交道,我的DOS知识基本上都是在长时间的瞎转中摸出来的,自然走了很多弯路,但还是没个系统性。受楼主的引荐我才知道这个论坛,来到这里我才知道自己以前盲目的瞎摸真是不如在这一个晚上!好了,我还是再想问问,关于if errorlevel的判断我理解,只是FOR命令还是不太清晰,它是怎样把 9 赋给了变量的?关于遮盖字符的思路我再出考虑一下;至于后面的程序“壳”,希望 willsort 以后抽个时间搞出来,我好好学习一下。
|
|
2004-1-9 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
6 楼』:
Re zww3008:
没想到你在哪,本来准备走了,索性再说几句吧。
刚才运行了你的程序,给你提供几点建议以供参考:
1,做程序,最好能符合已有的类似程序的习惯,这样便于用户迅速上手。所以建议你的程序中,更改密码的部分,新密码也能以遮盖字符显示,最好加上两次输入确认。输入密码的部分,则最好加一个确认操作,只有确认以后采取判断,而并非每输入一个字符就去判断,这样几增加了程序模块间的独立性,也避免了用户无意中猜中密码而未经确认直接进入系统的危险。
2,我们之所以去编程序,大部分是因为已有的程序不能满足我们的需要。所以,新程序最好能有自己的特色。可以考虑间隔时间输入或者输入习惯确认之类的功能。另外,如果将这个密码输入程序扩展为一个用户登陆程序,加上用户名的输入甚至据此分配不同的权限,是否更加理想?
3,关于那句for,其实可以将它用以下语句模拟:
if not errorlevel 10 if errorlevel 1 set $geiding=%geiding%1
if not errorlevel 10 if errorlevel 2 set $geiding=%geiding%2
......
if not errorlevel 10 if errorlevel 9 set $geiding=%geiding%9
set geiding=%$geiding%
仔细分析一下应该能够明白的。
4,至于那个“壳”,也许是我说的太抽象了些。其实,那就是用
command /c 批处理命令 批处理模块 批处理参数
创建一个新的命令解释环境来解释执行那个输入判断模块,而不是用call。你对这个应该不太陌生。
如果还有问题可以再讨论。不过最近几天我可能没有时间了。
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-1-9 00:00 |
|
|
zww3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
7 楼』:
Quote: | command /c 批处理命令 批处理模块 批处理参数
创建一个新的命令解释环境来解释执行那个输入判断模块,而不是用call。你对这个应该不太陌生。 |
|
其实我还真不懂,这个命令我没用过。看来以后还是得再找本书来再系统地学习一下。谢谢啦,祝新年快乐!过两天我也要回老家了。
|
|
2004-1-9 00:00 |
|
|
zww3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
8 楼』:
再将程序修改了一下,但又有了两个从没想到过的难题:
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 [%password%]==[%geiding%] 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
[/quote]
[此贴子已经被作者于2004-1-11 12:23:42编辑过]
|
|
2004-1-11 00:00 |
|
|
zww3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
9 楼』:
问题终于找到了!
1.经过我反复试验,原来不是什么变量数量限制的问题,SET 设置的变量数是没有什么限制的,只有伪参数%0~%9才有限制,要用到 shist 命令。
2.根本的原因就是变量空间过小的问题:Out of environment space(环境空间溢出),因空间溢出导致了后面的变量无法赋值才出错!在DOS下可能允许的变量空间较大这种情况好像不多见,在Windows 中就很容易遇到。解决方法如下。
3.本程序设定的密码为数字,允许的长度与变量空间有关,如果给定的变量空间较小,则可能无法输入和设定,运行出错!加大变量空间的设定方法:右击程序password.bat,点“属性--内存”在“初始环境”中选择最大值,确定后会自动生成一个MS-DOS的快捷方式文件,所作的设定也就保存在快捷方式文件里面,以后只要将这个快捷文件文件与原程序拷贝在一起使用(只要保证文件名相同,路径变了也没关,只要点原程序而不要点快捷方式)就可以了,而且可以修改和设定到几十位的密码,已经足够了。如果在将密码程序加载在 windows 98的 Autoexec.bat 在开机时运行,则没有发现变量空间和密码位数受限的情况,可不作任何设置直接使用。类似的问题 http://newdos.yginfo.net/dosart35.htm 中有介召,但没讲到本程序遇到的问题。
4.注意!如果密码程序 password.bat 是作为子程序被别的程序调用,则加大变量空间的设置应设主程序!password.bat不需设置。
[此贴子已经被作者于2004-1-11 12:44:46编辑过]
|
|
2004-1-11 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
10 楼』:
Re zww3008:
可以看得出来,你真得很下功夫!对此我十分钦佩。我以前也如你一般,现在,杂事太多了。根据你的程序和问题作以下答复:
1,变量大小的问题。
不能不提醒你,你对环境变量的使用未免太奢侈了一些,连提示语句也用它来表示,是有些舍本逐末了。要知道对于编程者来说,一块公共数据区的使用,是应该慎之又慎的。我自己编过的程序,一般很少用过三个以上的变量,如果一定要用到较多变量的时候,一般都会用加上环境空间大小检测模块,以免出错。
2,变量空间的问题。
如果你无法缩减变量,那么只能扩大环境空间。方法除了你上面提到的之外,还可以使用
command /e:空间大小 /c 批处理命令 批处理模块 批处理参数
的方式,这就是用command调用批处理的另一好处了。
3,标记设定的问题。
你的 verify 变量无法之直接在外壳中判定,原因很简单。因为两层壳使用的不是同一块环境空间,dos中使用command创建新壳,会按照参数e重新分配一块环境变量空间,然后将母壳的全部变量复制到子壳中,而在回收壳时,并不会复制子壳的变量到母壳。
所以,我说的“标记”,在这里不是指环境变量,而是指文件。比如下面的例子:
echo > pass.bat (子壳中)
......
if exist pass.bat goto end (母壳中)
4,模块调用的问题。
我所说的“子程序”并非一定要是一个独立的文件,他可以是程序中的一个区段,使用的方法如下:
Quote: | ::In shell
if [%1]==[$sub] 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讨论过,不再多说了。
[此贴子已经被作者于2004-1-11 13:38:03编辑过]
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-1-11 00:00 |
|
|
lianjl
初级用户
积分 192
发帖 23
注册 2004-1-8
状态 离线
|
|
2004-1-11 00:00 |
|
|
zww3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
12 楼』:
Quote: | ::In shell
if [%1]==[$sub] goto input
......
command /e:2048 /c %0.bat $sub
......
::In subroutine
:input
......
:end |
|
不好意思,这一段我还是没明白具体怎么布局,能说得更具体一点吗?现在主要是把两个文件合二为一后没法做到防止 Ctrl+C 终止了。
好像单就 command /e:2048 /c %0.bat 这条命令,是一条错误的命令啊。(在win98下试)。
[此贴子已经被作者于2004-1-13 17:29:59编辑过]
|
|
2004-1-12 00:00 |
|
|
willsort
元老会员
Batchinger
积分 4432
发帖 1512
注册 2002-10-18
状态 离线
|
『第
13 楼』:
Re zww308:
我不知道你是怎么测试的。下面贴出我的测试程序和测试结果(FOR 和 SET 用于测试环境空间,ECHO 和 PAUSE 用于测试 CTRL+BREAK 中断,在98下运行通过):
Quote: | @echo off
::In shell
if [%1]==[$sub] goto input
:start
command /e:1536 /c %0.bat $sub
if not exist pass.dat goto start
del pass.dat
goto end
::In subroutine
:input
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 0%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 1%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 2%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 3%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 4%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 5%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 6%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 7%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 8%%p=%%p%%p%%p%%p%%p%%p
for %%p in (1 2 3 4 5 6 7 8 9 0) do set 9%%p=%%p%%p%%p%%p%%p%%p
set
echo Note: Please press any key to exit...
echo Warning: Press Ctrl+Break/Ctrl+C not exit!
pause > nul
rem > pass.dat
:end |
|
[此贴子已经被作者于2004-1-14 9:33:03编辑过]
|
※ Batchinger 致 Bat Fans:请访问 [讨论]批处理编程的异类 ,欢迎交流与共享批处理编程心得! |
|
2004-1-14 00:00 |
|
|
drlzf
初级用户
爱之屋论坛管理员
积分 158
发帖 14
注册 2003-12-17
状态 离线
|
|
2004-1-14 00:00 |
|
|
zww3008
初级用户
积分 197
发帖 21
注册 2004-1-9
状态 离线
|
『第
15 楼』:
谢谢willsort:
我现在终于理解了一个很重要的问题,我的理论不足,多是在走弯路的实践中悟出来的,所以说跟willsort交流学东西很快,书上都学不到.
我原来的布局是这样的(比如说批文件名为CC.bat):
--------------------------
@echo off
::In shell
if [%1]==[$sub] goto subroutine
:start
command /e:1536 /c %0 $sub
if exist pass.dat goto end
goto start
::In subroutine
:subroutine
......(原来的子程序password.bat)
:quit
rem > pass.dat
cls
:end
del pass.dat
echo.
echo Run my BAT or enter windows ...
-------------------------------------
我是这样理解的:当双击CC.bat,系统用command启动运行CC.bat,在运行过程中遇到command /e:1536 /c %0 $sub,再启动一个command调用程序自身运行一遍,当调用完后,再返回到“if exist pass.dat goto end”一句处执行,是这样的吧?现在就知道上面的布局的问题在哪里了:当通过验证执行到:end后,又del pass.dat,调用自身完后返回执行“if exist pass.dat goto end goto start”时就又回去了。
不过,现在还存在几个问题:
1.还是有一个错误,“command /e:1536 /c %0.bat $sub”中用%0就代表了程序本身,不能再加上.bat扩展名,否则就出错了,我测试时出错应该就是这个原因。
2.当整个程序执行完后,“echo Run my BAT or enter windows ...”会被执行两遍!即如果将这个程序加载在前面作为一个权限审核,后面再加载用户程序时(不管是直接加在主程序内,还是用户程序作为独立子程序调用),用户程序会被执行两遍。所以我觉得还是将密码程序作为一个独立的子程序调用比较好。但这样一来也就还是没办法用“command /e:1536 /c %0 $sub”方法来解决了变量空间问题了。
|
|
2004-1-14 00:00 |
|