Batch file 批处理功能无法正常工作

Batch file 批处理功能无法正常工作,batch-file,vbscript,Batch File,Vbscript,不久前,我制作了一个可以从命令提示符或任何批处理文件调用的函数(只是为了好玩,我不知道它有什么用处)。它基本上只是让你的(微软)计算机说出你写的任何参数。 我最近得到了一些灵感,在其中添加了一个开关,可以读取文件的内容。我的独立脚本工作了,但当我将它添加到函数中时,它并没有像我希望的那样工作 代码如下: @echo off & setlocal enabledelayedexpansion if "%~1"=="/?" ( echo. echo TALK "Text"

不久前,我制作了一个可以从命令提示符或任何批处理文件调用的函数(只是为了好玩,我不知道它有什么用处)。它基本上只是让你的(微软)计算机说出你写的任何参数。 我最近得到了一些灵感,在其中添加了一个开关,可以读取文件的内容。我的独立脚本工作了,但当我将它添加到函数中时,它并没有像我希望的那样工作

代码如下:

@echo off & setlocal enabledelayedexpansion

if "%~1"=="/?" (
    echo.
    echo TALK "Text" [Parameters]
    echo.
    echo Text - The phrase you want to be spoken.
    echo.
    echo [Parameters]:
    echo              /f - Read the contents of a file. "Text" changes to the file path.
    echo.
    endlocal
    exit /b
)

if "%~2 X" equ "/f X" (

    if not exist %~1 (
        echo File does not exist or cannot be found.
        endlocal
        exit /b
    )

    set cont= 
    for /f "delims=" %%i in (%~1) do set cont=!cont! %%i
    :b
    echo Set a = Wscript.CreateObject("SAPI.SpVoice") > "Talk.vbs"
    echo a.speak "%cont%" >> "Talk.vbs"
    start /WAIT Talk.vbs
    del Talk.vbs
    endlocal
    exit /b
)

set text=%~1

echo set speech = Wscript.CreateObject("SAPI.spVoice") > "talk.vbs"
echo speech.speak "%text%" >> "talk.vbs"
start /WAIT talk.vbs
del Talk.vbs
endlocal
exit /b
不幸的是,我没有工作功能代码(在添加
/f
开关之前)

这是我最后的选择,因为我已经对它进行了大量的编辑,并仔细检查了代码,以找出可能存在的问题

另一件坏事是我没有注意到我改变了什么,所以我不能确切地告诉你我做了什么。我可以告诉你输出是什么

我第一次尝试时,它给出的输出
命令的语法不正确。

现在,原来的功能(只是将文本转换为语音)已经不起作用了。文件
Talk.vbs
(在该过程中创建)的内容是
a.speak”“

我会不断更新我的尝试,但了解我,我忽略了一些非常简单的事情

--编辑--
在某人的建议下,我在语法部分的方括号前加了克拉。没有任何更改。

在包含括号的echo语句中,尝试用克拉转义括号。我特别怀疑if语句中的回声部分地得到了字面上的评估

另一个小建议,我也将取代

start /WAIT Talk.vbs

我并不认为是
start/wait
导致了错误,但它确实导致了第二个控制台窗口临时出现,这并没有什么好的理由——或者不管怎样,只要脚本执行了那么远,它就会出现

我在这里做了一些其他建议的更改,例如不需要a/f开关。如果“%1”是存在的文件名,请读取它。否则,将其视为要阅读的文本。与使用单独的子程序读取文件和从输入中获取文本不同,需要做的只是变量具有不同的值

@echo off & setlocal enabledelayedexpansion

if "%1"=="/?" ( goto usage )
if "%1"=="" ( goto usage )
if "%1"=="--help" ( goto usage )
if exist "%1" (
    set txt=
    for /f "usebackq tokens=*" %%i in (%1) do set txt=!txt! %%i
) else (
    set txt=%1
)
echo Set a = Wscript.CreateObject^("SAPI.SpVoice"^) > "talk.vbs"
echo a.speak "%txt%" >> "talk.vbs"
cscript /nologo talk.vbs
del talk.vbs
endlocal
goto :EOF

:usage
echo.
echo TALK ["text"^|filename]
echo.
echo talk filename -- speaks the contents of filename
echo talk "text"   -- speaks the supplied text
endlocal
goto :EOF

除了转义括号外,如果参数为
“我想让它说的一些单词”
,你还必须将
如果存在%1
用引号括起来。也清理了一下。代码在底部,但首先是一个解释

如果在删除talk.vbs之前查看它,您会看到:

a.speak "!cont! contents of the file here" 
这是因为以下代码:

for /f "delims=" %%i in (%~1) do set cont=!cont! %%i
:b
echo Set a = Wscript.CreateObject("SAPI.SpVoice") > "Talk.vbs"
如果打开echo并查看代码,您将看到最后一个未跳过的
正在获取for循环的内容并将其包含在重定向中

已更正和清除的代码:

@echo off & setlocal enabledelayedexpansion
if "%~1"=="/?" (
    echo.
    echo TALK "Text" [Parameters]
    echo.
    echo Text - The phrase you want to be spoken.
    echo.
    echo [Parameters]:
    echo              /f - Read the contents of a file. "Text" changes to the file path.
    echo.
    endlocal
    exit /b
)
set text=
if [%2]==[/f] (
    if exist "%~1" (
        for /f "usebackq delims=" %%i in (%1) do set text=!text! %%i
    ) else (
        endlocal
        exit /B
    )
)
if [%2]==[] set text=%~1

echo set speech = Wscript.CreateObject^("SAPI.spVoice"^) > "talk.vbs"
echo speech.speak "%text%" >> "talk.vbs"
cscript //NoLogo //B talk.vbs
del Talk.vbs
endlocal
exit /b

编辑:修复了安德烈M

用括号指出的语句的
,你指的是方括号,对吗?我试过了,没有区别。不,他指的是括号。示例
echo Set a=Wscript.CreateObject(“SAPI.SpVoice”)>“Talk.vbs”
需要
echo Set a=Wscript.CreateObject^(“SAPI.SpVoice”^)>“Talk.vbs”
正确。正如您的问题中显示的代码一样,
将比您预期的早6行结束您的
if
语句,从而导致该错误消息。谢谢。我选择Patrick Meinecke的答案而不是你的答案,因为他保留了与我的原始代码几乎相同的格式,但你的代码同样有用。不带引号的
%~1
条目可能是个问题。另一个不带引号的
%~1
for/f
循环中。您可能需要将
usebackq
添加到选项中,以便将
%~1
周围的双引号视为文件名分隔符,而不是字符串分隔符。只是想知道,使用cscript命令比仅仅启动它有什么好处吗?
@echo off & setlocal enabledelayedexpansion
if "%~1"=="/?" (
    echo.
    echo TALK "Text" [Parameters]
    echo.
    echo Text - The phrase you want to be spoken.
    echo.
    echo [Parameters]:
    echo              /f - Read the contents of a file. "Text" changes to the file path.
    echo.
    endlocal
    exit /b
)
set text=
if [%2]==[/f] (
    if exist "%~1" (
        for /f "usebackq delims=" %%i in (%1) do set text=!text! %%i
    ) else (
        endlocal
        exit /B
    )
)
if [%2]==[] set text=%~1

echo set speech = Wscript.CreateObject^("SAPI.spVoice"^) > "talk.vbs"
echo speech.speak "%text%" >> "talk.vbs"
cscript //NoLogo //B talk.vbs
del Talk.vbs
endlocal
exit /b