0

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

这是代码:

@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开关之前)。

这对我来说是最后的手段,因为我已经对其进行了大量编辑并搜索了代码以找出可能存在的问题。

另一个不好的事情是我没有注意到我改变了什么,所以我不能准确地告诉你我尝试了什么。我可以告诉你输出是什么。

我第一次尝试时,它给出了输出The syntax of the command is incorrect.

现在原始功能(只是将文本转换为语音)不再起作用了。该文件的内容Talk.vbs(在此过程中生成)是a.speak "".

我会不断更新我的尝试,但我知道这是我忽略的非常简单的事情。

--EDIT-- 在某人的建议下,我在语法部分的方括号前加上了克拉。没有改变。

4

2 回答 2

1

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

另一个小建议,我也会替换

start /WAIT Talk.vbs

cscript /nologo Talk.vbs

这并不是我认为start /wait是导致错误的原因,而是它确实会导致第二个控制台窗口无缘无故地临时出现——或者无论如何,只要你的脚本执行那么远,它就会出现。

我在这里做了一些其他建议的更改,例如消除对 /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
于 2013-02-10T02:43:19.930 回答
1

除了转义括号外,您还必须if exist %~1用引号括起来以防"some words I want it to say". 也清理了一下。代码在底部,但首先是解释。

如果您在 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

编辑:修复了forAndriy M 指出的声明

于 2013-02-10T03:38:05.443 回答