C# process.Kill 不会立即停止正在运行批处理文件的进程
Posted
技术标签:
【中文标题】C# process.Kill 不会立即停止正在运行批处理文件的进程【英文标题】:C# process.Kill does not immediately stop a process that is running a batch file 【发布时间】:2017-04-14 18:25:35 【问题描述】:问题:我遇到了一个问题,我无法使用 processName.Kill()
立即停止在 C# 应用程序(进程)中运行的批处理文件
在我的项目中,批处理文件将运行几个 python 脚本,总共需要大约 30 分钟才能完成。它会偶尔将几行输出转储到控制台,我正在使用相关进程的标准输出捕获这些输出。
我正在设置并开始这个过程:
var process = new Process
StartInfo = new ProcessStartInfo
UseShellExecute = false,
FileName = @"C:\Test.bat",
WorkingDirectory = @"C:\",
RedirectStandardOutput = true,
,
;
process.Start();
我正在测试的批处理文件非常简单:
echo starting
timeout /t 4
echo it worked
我正在使用来自共享取消令牌源的取消令牌并在 2000 秒后取消。我已将以下事件附加到令牌:
ct.Register(() =>
process.Kill();
);
我将标准输出逐行发送到字符串的阻塞集合,如下所示:
Task.Factory.StartNew(() =>
while (!streamReader.EndOfStream)
var line = streamReader.ReadLine();
if (line == null) break;
_blockingCollection.Add(line);
_blockingCollection.CompleteAdding();
);
我预计会发生什么:因为进程已被取消令牌引发的事件杀死,我希望 streamReader.Readline()
方法立即返回 null 或抛出异常。相反,它等待批处理文件中的超时完成,然后返回超时打印的完整行。在我的实际应用程序中,它可能会等待 10-15 分钟以等待脚本的下一个输出。
我是否误解了process.Kill()
的工作原理?是超时行为奇怪吗?在理想情况下,我希望流阅读器立即停止阅读并跳出 while 循环。
我尝试通过在每次进程输出接收到新数据时引发一个事件来做到这一点,但是我无法同步这些以按正确的顺序运行,因为脚本倾向于同时转储数百行输出
谢谢
【问题讨论】:
您误解了 .bat 文件的工作原理 Kill() 有多个进程。执行 .bat 文件的命令处理器 (cmd.exe),您点击了那个。但不是执行超时的进程 timeout.exe。通常没有 100% 可靠的方法来发现并及时终止任何由 .bat 文件启动的进程。你可能会领先with this,但这是一场比赛。 有没有一种方法可以像在命令窗口中按 ctrl+c 一样杀死进程? 不要使用process.Kill
,而是尝试将 Ctrl-C (Ascii 3) 后跟 Y\n
提供给 .bat (cmd.exe) 文件的标准输入。
【参考方案1】:
(对不起,我无法发表评论。)
我想这是因为命令:timeout
在这里很麻烦。我曾经试图用命令提示符杀死一个timeouting
批处理,它的发生与上面相同。在timeouting
完成之前无法终止批处理。
也许你可以在杀死批次后尝试
Process.Kill("timeout.exe")
。
抱歉,如果我误解了您的问题。我只是这里的新手。
【讨论】:
以上是关于C# process.Kill 不会立即停止正在运行批处理文件的进程的主要内容,如果未能解决你的问题,请参考以下文章
在 C# 中使用 process.kill() 关闭了单词 doc,但是当打开一个新单词时,它会打开最后保存的单词 doc。我想要新的 word 文档窗口