批处理之家's Archiver

Batcher 发表于 2009-4-11 13:21

批处理模拟choice命令(20090614更新)

[color=Blue]【效果1】不生成临时文件、不使用 Choice、不使用 Set /p var=...达到代替 Choice和判断键值的方法如下:[/color][code]@echo off && setlocal && cls
chcp 437 >nul
graftabl 936 >nul

set /p=请选择 [ 回车键 --- 执行A          其它键 --- 执行B ]:<nul
echo exit|cmd/kprompt $_e 100 CD 16 B4 4C CD 21$_g$_|debug>nul

echo.&echo.&echo.
if [%errorlevel%]==[13] ( goto :A ) else ( goto :B )

:A
        ::  按回车符到这里执行
        echo 这里是标签: A
        goto :End

:B
        ::  按其它键到这里执行
        echo 这里是标签: B
        goto :End

:End

        ::  用于测试键值的代码段
        ::  如果希望代替Choice外部命令,则这个代码段可以测试出不同的键值交由%ErrorLevel%判断

        echo 所输入的ASCII码键值: %errorlevel%

Pause[/code]每次所按的键值都在 %errorlevel% 变量中,可以使用 IF 语句来判断用户所按键值,再根据键值做更复杂的处理。

键值: 回车键  13
    ESC键   27

更多的ASCII码表在论坛搜索中可找到~:)
ascii码大全——(0~255)已更新[url]http://www.cn-dos.net/forum/viewthread.php?tid=25050[/url]

[原创]CMD批处理获取文件的ASCII码
[url]http://www.cn-dos.net/forum/viewthread.php?tid=26521[/url]

上面实现原理: 调用 Debug 但不生成临时文件写入汇编代码。

        int 16            ; 调用键盘中断
        mov ah,4c
        int 21      ; 带参数(用户所按键值在 AL 寄存器中)返回DOS
                ; 把用户所按键值返回给 %errorlevel%

然后由 if 判断 %errorlevel% 的不同取值决定程序走向:)

) 已知问题

  在调用 Debug 时,在网吧的机器上(是网吧禁止了可能存在的危险工具);
  在有些日文版的机器上使用 echo exit|cmd/kprompt...操作时也会出错,由于个性化设置或其它路径等原因;
  或是极少见的情况某些精减版XP,未带有Debug.exe外部工具。
  在一些装有杀病毒软件的机器上有可能这种操作方式会让杀病毒软件拦截掉~:)
  在桌面双击方式运行一个批处理程序 和 先进入CMD后再运行一个批处理程序它们有着细微的差别,echo exit|cmd/k..在后者兼容较好。

[color=Blue]【效果2】n秒后不按任何键或是按某个键可以判断出用户的选择,原理如下:[/color]

) A主批处理文件:

  在A主批处理文件中 START 出一个新窗口,递归调用自己通过%1来判断是递归加载参数。

  然后被START出的新批处理窗口我们叫它脚本B。

  在脚本B中使用 Title 设置窗口标题(为了是杀掉它方便)。
  在脚本B中 set /p var=接收用户键盘输入,如果输入回车键,则在脚本B中采用  exit 返回码 方式来通知这个批处理是正常接收了键盘输入的情况下退出的。

  假如在START出的脚本B中客户就成心不打任何键,也没关系。

  在主脚本A中START出这个窗口以后的下一句可是一个延时命令,如果延时10秒钟以后,就杀掉窗口B,不管窗口B是否正常退出,只要判断 %errorlevel% 就知道脚本B是否返回了一个约定码。

  然后如果脚本B返回的 %errorlevel% 为约定码,则脚本B是自然收到客户输入才正常退出的,所以执行主代码段A内的标签A。

  (因为如果脚本B是在正常的约定时间,如10秒内输入的回车,则正常退出不可能被杀,所以杀的时候找不到进程到个>nul就行了)

  如果脚本B在接收客户输入时,客户成心就是不输入任何键,则脚本B必然被脚本A杀掉,所以根本返回不了约定的返回码。

  所以 if %error% ……就知道了客户什么也没输入,所以执行A主批处理中的标签B。

) 以上是实现原理。

原文地址:[url]http://www.cn-dos.net/forum/viewthread.php?tid=27149[/url]

qzwqzw 发表于 2009-6-14 11:34

麻烦楼主在ZT的时候
能在仔细一些

楼上的原理和代码完全不是一回事
原理中监护set/p进程的方法被作者自己证明行不通
因为set/p始终是需要回车确认才会赋值的
所以最后才改用了prompt+debug+DOS21#中断的办法

所以最好把原理那段删除或改写

Batcher 发表于 2009-6-14 11:53

回复 2楼 的帖子

顶楼已更新,感谢qzwqzw兄指正。

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.