Выход из пакетного скрипта при вводе - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть пакетный файл, выполняющий повторяющуюся работу, который выполняется из приложения C # (менеджера заданий) как процесс, и его необходимо остановить «мягким» способом (не Process.Kill(), а скорее чтение вводамежду рабочими итерациями).

Я выбрал перенаправление stdin скрипта и отправку строки "stop", когда пришло время.В пакете я должен прочитать команду «стоп» (или даже любой ввод, просто получить строку) и выйти.Однако это легче сказать, чем сделать.

Следующая команда получает любые входные данные и выходит:

set /p x=&exit

Но, будучи однопоточным, пакет не может выполнять итерации во время ожиданиядля ввода.Итак, я вижу 2 способа справиться с этим:

1.Многопоточность

Я не нашел никакого способа сделать это в пакетном режиме, кроме команды start.Я попробовал это:

start set /p x=&exit

Но, похоже, он создает новый процесс , поэтому мой ввод не достигает его, и даже если я нашел способ перенаправить его туда, вызываявыход в него не помог бы мне никоим образом, так как это не процесс моей партии.Вот полный пример скрипта:

@echo off
start set /p x=&exit
:work
ping 127.0.0.1
goto :work

2.Тайм-аут при чтении ввода

Здесь есть команда choice, как показано здесь .Но тайм-аут не работает, когда пакет выполняется из C # - команда продолжает ожидать ввода, хотя тайм-аут и значение по умолчанию определены.Вот полный пример сценария:

@echo off
:work
ping 127.0.0.1
choice /T 5 /C sc /D c
set _e=%ERRORLEVEL%
if %_e%==1 echo Stopped
if %_e%==2 echo Continue&goto :work

"s" из "stop" достаточно для успешной остановки сценария, но происходит только 1 итерация - команда выбора просто ожидает ввода.Вот код C #, порождающий процесс, довольно стандартный:

            Process script = new Process();
            script.StartInfo = new ProcessStartInfo("batfile.bat");
            script.StartInfo.UseShellExecute = false;
            script.StartInfo.WorkingDirectory = Environment.GetEnvironmentVariable("ROOT");
            script.StartInfo.RedirectStandardInput = true;
            script.StartInfo.RedirectStandardOutput = true;
            script.StartInfo.RedirectStandardError = true;
            script.OutputDataReceived += new DataReceivedEventHandler(HandleStdout);
            script.ErrorDataReceived += new DataReceivedEventHandler(HandleStderr);
            script.Start();

Я подозреваю, что он как-то связан с перенаправлениями: stdout висит на строке [S, C]? , потому что естьпосле него нет новой строки.Но мне нужны эти перенаправления ...

Конечно, есть 3-й вариант , который отправляет ввод "continue" или пустую строку каждую секунду или около того, поэтому скрипт просто должен выглядетьдля "стопа", но, на мой взгляд, это немного уродливо, поэтому я стараюсь избежать этого любой ценой, особенно если я использую вариант 1 или 2 или получу лучшее предложение.

...