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スイッチを追加する前)。

これは私にとって最後の手段です。私はそれを大幅に編集し、コードを精査して問題の原因を突き止めました。

もう 1 つの悪い点は、何を変更したかを書き留めていなかったことです。そのため、何を試したかを正確に伝えることはできません。ただし、出力が何であるかはわかります。

初めて試したとき、出力が得られましたThe syntax of the command is incorrect.

元の機能 (テキストを音声に変換するだけ) が機能しなくなった時点です。ファイルTalk.vbs(プロセス中に作成された)の内容はa.speak "".

私は自分の試みを更新し続けますが、私が見落としているのは本当に単純なことだと知っています.

--編集-- 誰かの提案で、構文セクションの角括弧の前にカラットを置きました。何も変わっていません。

4

2 に答える 2

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"

エコーをオンにしてコードを見ると、エスケープ)されていない最後のループが 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

編集:for Andriy Mが指摘した声明を修正

于 2013-02-10T03:38:05.443 に答える
1

括弧を含む echo ステートメントでは、括弧をカラットでエスケープしてみてください。特に、if ステートメント内のエコーが部分的に文字通り評価されていると思われます。

もう1つのマイナーな提案、私も置き換えます

start /WAIT Talk.vbs

cscript /nologo Talk.vbs

start /waitがエラーの原因であるとは思いませんが、正当な理由もなく一時的に 2 つ目のコンソール ウィンドウが表示されます。または、スクリプトがそこまで実行されるたびに表示されます。

ここでは、/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 に答える