我有一个做重复工作的批处理文件,它是从C#应用程序(作业管理器)作为流程执行的,需要以“温和”的方式停止(不是Process.Kill()
,而是在工作迭代之间读取输入)。
我选择了重定向脚本的stdin并在需要时发送“停止”行。在批处理中,我必须阅读“停止”命令(甚至任何输入,仅获得一行)并退出。但是事实证明说起来容易做起来难。
以下命令获取任何输入并退出:
set /p x=&exit
但是,由于是单线程的,所以批处理在等待输入时无法进行迭代。所以我看到了两种处理方法:
1。多线程
除start
命令外,我没有找到任何批量处理的方法。我尝试过:
start set /p x=&exit
但是它似乎创建了一个新过程,因此我的输入无法到达,即使我找到了一种将其重定向到此处的方法,在其中调用exit也无济于事任何方式,因为这不是我的批处理过程。这是一个完整的脚本示例:
@echo off
start set /p x=&exit
:work
ping 127.0.0.1
goto :work
2。输入阅读超时
有一个choice
命令,如here所示。但是,当从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”足以成功停止脚本,但是仅发生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个选项,它每秒钟发送一次“继续”或空行的输入,因此脚本只需要查找“停止”,但这有点丑陋我认为,因此我将不惜一切代价避免使用它,尤其是当我选择方法1或2进行工作或获得更好的建议时。