中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 会员 | 搜索 | 上传 | 帮助 »
中国DOS联盟论坛 » DOS批处理 & 脚本技术(批处理室) » 可自定义密码的密码程序(批处理)[转帖]
« [1] [2] »
作者:
标题: 可自定义密码的密码程序(批处理)[转帖] 上一主题 | 下一主题
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
状态 离线
『第 11 楼』:  

太好了,如此讨论真是长见识!

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
状态 离线
『第 14 楼』:  

有意思!



爱之屋网站
爱之屋论坛
爱之屋影院
2004-1-14 00:00
查看资料  发送邮件  访问主页  发短消息 网志  OICQ (22926416)  编辑帖子  回复  引用回复
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
查看资料  发送邮件  发短消息 网志   编辑帖子  回复  引用回复
« [1] [2] »
请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: