Согласно help documentation of TortoiseSVN вам нужно сделать явное перенаправление на консоль (устройство con
):
When debugging hook scripts you may want to echo progress lines to the DOS console, or insert a pause to stop the console window disappearing when the script completes. Because I/O is redirected this will not normally work. However you can redirect input and output explicitly to CON to overcome this. e.g.
echo Checking Status > con
pause <con> con
К сожалению, это не работает с командой choice
, как это, кажется, не принимает перенаправления ввода с устройства con
:
>>> choice < con
ERROR: The handle is invalid.
простой обходной использовать set /P
команда, которая поддерживает перенаправление из con
:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Loop structure for prompting user:
:CONFIRM
rem // Display prompt and await user input:
<con> con set /P SELECT="Continue? [Yes/No]?"
rem // Check user input case-insensitively:
if /I "%SELECT%"=="Y" exit /B 0
if /I "%SELECT%"=="Yes" exit /B 0
if /I "%SELECT%"=="N" exit /B 1
if /I "%SELECT%"=="No" exit /B 1
rem // Repeat prompt in case of invalid entry:
goto :CONFIRM
endlocal
exit /B
Недостатком этого является то, что запись должна быть прекращена с RETURN, в отличие от choice
команды, которая принимает один ключ ввода.
Вот лучший подход, который показывает один ключ приглашение аналогично команде choice
. Это (неверно) использует команду xcopy
и ее способность принимать перенаправленный ввод в запросе подтверждения копирования, которое появляется, когда поставляется переключатель /W
. Также обратите внимание на пояснительные замечания:
@echo off
setlocal EnableExtensions EnableDelayedExpansion
rem // Loop structure for prompting user:
:CONFIRM
rem // Display prompt without trailing line-break:
<nul> con set /P ="Continue? [Y/N]?"
rem /* Let `xcopy` wait for a single-key entry using its `/W` switch;
rem `/L` tells `xcopy` to actually copy nothing; to avoid problems
rem with inexistent paths, use this script's path as source file
rem and the system's temporary directory as the target location: */
< con (
for /F "delims=" %%L in ('
xcopy /L /W "%~f0" "%TMP%\"
') do (
rem /* Capture the copy confirmation prompt of `xcopy /L /W`,
rem `Press any key when ready to begin copying file(s)`,
rem together with the character entered by the user, which
rem is appended to the prompt message: */
set "CHAR=%%L"
rem /* Leave loop upon first iteration, because we are not
rem interested in any copying results and summaries: */
goto :SKIP
)
)
:SKIP
rem // Extract the last character, which is the actual user input:
set "CHAR=!CHAR:~-1!"
rem // Display user entry:
> con echo(!CHAR!
rem // Check user input case-insensitively:
if /I "!CHAR!"=="Y" exit /B 0
if /I "!CHAR!"=="N" exit /B 1
rem // Repeat prompt in case of invalid entry:
goto :CONFIRM
endlocal
exit /B
Если неожиданный вход предусмотрен, запрос перепечатана на следующей строке и новый пользовательский ввод ожидается.
Чтобы избежать повторной печати текста подсказки в случае неожиданного пользовательского ввода, используйте следующий скрипт:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "MESSAGE=Confirm? [Y/N]?"
rem // Retrieve back-space character:
for /F %%Z in ('prompt $H ^& for %%Z in ^(.^) do rem/') do set "BS=%%Z"
rem // Retrieve carriage-return character:
for /F %%Z in ('copy /Z "%~f0" nul') do set "CR=%%Z"
rem // Loop structure for prompting user:
:CONFIRM
setlocal EnableDelayedExpansion
rem // Display prompt without trailing line-break:
> con < nul set /P ="%BS% !CR!!MESSAGE!"
endlocal
rem /* Let `xcopy` wait for a single-key entry using its `/W` switch;
rem `/L` tells `xcopy` to actually copy nothing; to avoid problems
rem with inexistent paths, use this script's path as source file
rem and the system's temporary directory as the target location: */
< con (
for /F "delims=" %%L in ('
xcopy /L /W "%~f0" "%TMP%\"
') do (
rem /* Capture the copy confirmation prompt of `xcopy /L /W`,
rem `Press any key when ready to begin copying file(s)`,
rem together with the character entered by the user, which
rem is appended to the prompt message: */
set "CHAR=%%L"
rem /* Leave loop upon first iteration, because we are not
rem interested in any copying results and summaries: */
goto :SKIP
)
)
:SKIP
setlocal EnableDelayedExpansion
rem // Extract the last character, which is the actual user input:
set "CHAR=!CHAR:~-1!"
rem // Display user entry without trailing line-break:
> con < nul set /P ="!CHAR!"
rem // Check user input case-insensitively:
if /I "!CHAR!"=="Y" exit /B 0
if /I "!CHAR!"=="N" exit /B 1
endlocal
rem // Repeat prompt in case of invalid entry:
goto :CONFIRM
echo/
endlocal
exit /B
Это комплексное решение, которое позволяет использовать специальные символы, как !
, ^
и "
тоже ,
Вот вполне аналогичное решение, опираясь на команде replace
, вместе с его /W
выключателем, а также без перепечатки подсказки в случае неожиданного пользовательского ввода. Поскольку replace
печатает характер нажатия клавиши в отдельной строке, нет никакой необходимости, чтобы разделить его на другую строку (в отличие от xcopy /W
):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "MESSAGE=Confirm? [Y/N]?"
rem // Retrieve back-space character:
for /F %%Z in ('prompt $H ^& for %%Z in ^(.^) do rem/') do set "BS=%%Z"
rem // Retrieve carriage-return character:
for /F %%Z in ('copy /Z "%~f0" nul') do set "CR=%%Z"
rem // Loop structure for prompting user:
:CONFIRM
setlocal EnableDelayedExpansion
rem // Display prompt without trailing line-break:
> con < nul set /P ="%BS% !CR!!MESSAGE!"
endlocal
rem /* Let `replace` wait for a single-key entry using its `/W` switch;
rem `/U` tells `replace` to actually do nothing; to avoid problems
rem with inexistent paths, use this script's path as source file
rem and its parent directory as the target location: */
< con (
for /F "skip=1 delims=" %%L in ('
replace /W /U "%~f0" "."
') do (
rem /* Capture the confirmation user input of `replace /W /U`,
rem skipping the prompt `Press any key to continue . . .`: */
set "CHAR=%%L"
rem /* Leave loop upon first iteration, because we are not
rem interested in any replacement results and summaries: */
goto :SKIP
)
)
:SKIP
setlocal EnableDelayedExpansion
rem // Display user entry without trailing line-break:
> con < nul set /P ="!CHAR!"
rem // Check user input case-insensitively:
if /I "!CHAR!"=="Y" exit /B 0
if /I "!CHAR!"=="N" exit /B 1
endlocal
rem // Repeat prompt in case of invalid entry:
goto :CONFIRM
echo/
endlocal
exit /B
В соответствии с [справочной документации TortoiseSVN] (https: //tortoisesvn.net/docs/release/TortoiseSVN_en/tsvn-dug-settings.html#tsvn-dug-settings-hooks) вам нужно выполнить ** явное перенаправление на консоль (устройство 'con') **, например' echo Проверка состояния> con' или 'pause < con > con' ... – aschipfl
@aschipfl' choice/M "Продолжить фиксацию?«< con > con' дает ошибку: ОШИБКА: дескриптор недействителен. – Gqqnbig
Я никогда не делал этого с помощью команды' choice', я использовал только '> con echo' и' pause < con > con' для отладки, которая работает, вы также можете попробуйте использовать '< con > con set/P' ... – aschipfl