有趣的批处理文件有些麻烦

时间:2017-02-13 08:19:16

标签: batch-file text typing

所以,我只是一个随便的小伙伴,他发现你可以用批量做一些有趣的事情。无论如何,我试图在一个朋友的usb上做一个很酷的隐藏文件夹类型交易。

唯一的问题是我真的希望它输出问题,比如真正的人工智能或人的问题。我在这里找到了实际打字的解决方案。 Link

这是解决方案示例



@echo off
:: Ghost typer
setlocal enableextensions enabledelayedexpansion

set lines=6


set "line1=Twinkle twinkle little star"
set "line2=How I wonder what you are"
set "line3=Up above the world so high"
set "line4=Like a diamond in the sky"
set "line5=Twinkle twinkle little star"
set "line6=How I wonder what you are"


for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"

for /L %%a in (1,1,%lines%) do set num=0&set "line=!line%%a!"&call :type

pause>nul
goto :EOF

:type
set "letter=!line:~%num%,1!"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul

:: adjust the 3 in the line below: higher is faster typing speed

for /L %%b in (1,3,%delay%) do rem
if "%letter%"=="" echo.&goto :EOF
set /a num+=1
goto :type
&#13;
&#13;
&#13;

所以我只是把它换成了我自己的线路。&#34;输入密码..&#34;确保将其设置为一行。

但那就是我遇到问题的地方。它似乎是一个循环或其他东西。每当我试图让它转到一组新命令时,它就会破坏整个事情。我在哪里可以添加一个goto来启动一个新的命令?

1 个答案:

答案 0 :(得分:0)

如果我完全理解您在帖子和comment中描述的问题,那么您似乎并不完全理解您的代码。我将(尝试)解释一下为什么cmd解释器永远无法访问脚本中的某些位置。结果是这些地方的代码永远不会被执行。

让我们考虑一下代码的第一部分(cmd解释器的开头):

@echo off
:: Ghost typer
setlocal enableextensions enabledelayedexpansion

set lines=6


set "line1=Twinkle twinkle little star"
set "line2=How I wonder what you are"
set "line3=Up above the world so high"
set "line4=Like a diamond in the sky"
set "line5=Twinkle twinkle little star"
set "line6=How I wonder what you are"


for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"

for /L %%a in (1,1,%lines%) do set num=0&set "line=!line%%a!"&call :type

pause>nul
goto :EOF

使用@echo off禁用每个命令的打印,启用delayed expansion,设置包含文本行的所有变量,使用for /f循环获取退格符将在文本输入过程中使用(我不太明白为什么prompt命令与for循环和双引号一起使用)并使用for /L循环迭代所有您的lines并使用call将其输入到脚本第二部分中实现的:type函数中。之后pause>nul将导致控制台等待,直到用户按下某个键。最后 goto :EOF用于终止当前批处理脚本的执行(或者&#34; context&#34;,进一步查看)否则cmd-interpreter将继续执行:type子程序下的代码是一个额外的时间(很可能不是你的意图)。如Microsoft's documentation for the goto command中所述,:EOF是一个预定义标签,可用于退出当前批处理脚本。所以你放在goto :EOF下的任何内容都将永远不会被执行或者至少不会在同一个&#34;上下文中#34; (进一步了解与#34;相同的背景&#34;)的含义。

但是,如何执行:type子例程并且goto :EOF没有退出批处理脚本?

:type
set "letter=!line:~%num%,1!"
set "delay=%random%%random%%random%%random%%random%%random%%random%"
set "delay=%delay:~-6%"
if not "%letter%"=="" set /p "=a%bs%%letter%" <nul

:: adjust the 3 in the line below: higher is faster typing speed

for /L %%b in (1,3,%delay%) do rem
if "%letter%"=="" echo.&goto :EOF
set /a num+=1
goto :type

这要归功于call命令。 :type只是一个像其他人一样的标签,但我称之为子例程的原因是因为你使用call而不是goto来执行它下面的内容。 goto只会跳转到你给它的标签,忘记它在goto之前所做的事情。另一方面,call命令将在执行脚本的上下文之上创建新的上下文。这样,当新的上下文关闭并退出时,可以回到脚本执行停止在call之前停止的位置(有点像调用和从子例程返回)。要退出该上下文,cmd解析器需要遇到(脚本)文件的正常结束,显式exit命令,或者在此情况下需要goto :EOF。即使在:type子例程的上下文中,goto :type下面的代码也不会被执行。事实上,在for /L标签下的:type之后有2个案例:

  1. %letter%为空:在这种情况下,将打印一个空行(echo.),由于goto :EOF,上下文将被关闭。这意味着它会回到脚本的上下文中(它将继续for /L迭代您的文本)
  2. %letter%不为空:变量num然后递增,cmd解释器跳回:type标签(因为goto :type)而没有到达代码在goto :type下(获得gotocall之间的差异?如果是call,它会在某个时刻执行其下的代码)。
  3. 现在,我可以向您展示可以添加必须执行的代码的位置以及代码不会执行的地方除了,如果您在这些地方放置标签并在可以添加代码的区域中使用gotocall(谨防差异和危险)到该标签。我还修改了您使用&for /Lif&使您的代码更难以理解。在你的情况下,他们并不是真的需要,所以我将每个命令放在自己的行上并用(...)括起命令。

    @echo off
    :: Ghost typer
    setlocal enableextensions enabledelayedexpansion
    
    set lines=6
    
    
    set "line1=Twinkle twinkle little star"
    set "line2=How I wonder what you are"
    set "line3=Up above the world so high"
    set "line4=Like a diamond in the sky"
    set "line5=Twinkle twinkle little star"
    set "line6=How I wonder what you are"
    
    
    for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "BS=%%a"
    
    REM Here is place OK 1
    REM Gets executed before the text prints
    
    for /L %%a in (1,1,%lines%) do (
        set num=0
        set "line=!line%%a!"
        call :type
    )
    
    REM Here is place OK 2
    REM Gets executed after the text prints
    
    pause>nul
    goto :EOF
    
    ! THIS PART IS NEVER REACHED BY THE CMD-INTERPRETER !
    
    :type
    set "letter=!line:~%num%,1!"
    set "delay=%random%%random%%random%%random%%random%%random%%random%"
    set "delay=%delay:~-6%"
    if not "%letter%"=="" set /p "=a%bs%%letter%" <nul
    
    :: adjust the 3 in the line below: higher is faster typing speed
    
    for /L %%b in (1,3,%delay%) do rem
    if "%letter%"=="" (
        echo.
        REM Place OK 3
        REM Here can come code that gets executed after each line is printed
        goto :EOF
    )
    set /a num+=1
    goto :type
    
    ! THIS PLACE WILL NEVER BE REACHED BY THE CMD-INTERPRETER EITHER !
    

    我希望这篇长篇文章有所帮助。如果你有任何问题,请不要犹豫。

    祝你好运!