c#-关闭过程由我启动,子进程由启动过程

时间:2019-06-23 20:10:48

标签: c# process stdin shutdown processstartinfo

我有一些控制台应用程序,我想在我的C#WinForms应用程序中对其进行控制。

基本上,我已经完成了几乎所有的工作,除了关闭我启动的过程。

启动过程时,我已经设置了所有内容,所以:

process.StartInfo.FileName = @"file.exe";
process.StartInfo.WorkingDirectory = Environment.CurrentDirectory;
process.StartInfo.Arguments = "";
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.CreateNoWindow = true; // important - want to grab stdout
process.StartInfo.RedirectStandardInput = true;
process.Start();
process.BeginErrorReadLine();
process.BeginOutputReadLine();
process.StandardInput.AutoFlush = true;

stdout已正确重定向。

我已经准备好发送stdin消息,但是我的进程没有收到它们或忽略它们(尚不确定)。

我看到了两个潜在的问题(当然还有我的代码中的问题;))

    我正在启动的
  1. 进程正在启动他的子进程,可能stdin必须直接指向该子进程,但它不是我直接产生的。

  2. 可能不仅我必须向子进程发送消息,而且还要向整个组发送消息。但是process.Start根本不与组打交道,因此我现在无法对此进行控制。

  3. 问题可能与CreateNoWindow有关,这对我很重要。

process.Close();也没有做好他的工作。

process.Kill();在工作,但是它仅杀死由我启动的进程,由我启动的进程产生的子进程-保持活动状态。

最后-我能够杀死所有进程,方法是获取它们的ID并打电话将其一一杀死,但是杀死进程会破坏它们的工作,这对我来说是个问题。我想向他们发送信号以使其关闭,如果它们不响应,则最终将其杀死。

我的尝试是:

1。

process.StandardInput.WriteLine("\x3");
process.StandardInput.Close();
process.Close();

2。

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool AttachConsole(uint dwProcessId);

[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern bool FreeConsole();

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetConsoleCtrlHandler(HandlerRoutine handler, bool add);

FreeConsole();

if (AttachConsole((uint)process.Id))
{
    SetConsoleCtrlHandler(null, true);
    GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, (uint)Process.Id);
    FreeConsole();
    SetConsoleCtrlHandler(null, false);
}

我还尝试对由我启动的进程产生的子进程执行StandardInput.WriteLine,但是我当然遇到了一个错误,因为我没有重定向标准输入,所以我不能这样做。

我几乎耗尽了所有想法。想过要使用某种SendMessageA并尝试按击Ctrl + C吗?

我知道,如果我直接从cmd.exe开始尝试抓取的进程,则Ctrl + C可以正常工作,并且我可以停止应用程序。

编辑1

更多详细信息。

我已经确认我能够将自己附加到两个子进程的控制台上-一个由我启动,另一个由我启动。

GenerateConsoleCtrlEvent报告两者均正确,但仍无人关闭。

另一方面,CTRL_BREAK_EVENT似乎已被接受o_O但是我的主窗口也正在关闭,并且似乎该事件没有正常关闭,而是等效的终止操作...

编辑2

PostMessage和SendMessage似乎不能很好地工作,但可以得到任何帮助。

编辑3

最后是taskkill的输出,这也许可以说明情况吗?

taskkill /PID 13384 /T
ERROR: The process with PID 5456 (child process of PID 13384) could not be terminated.
Reason: This process can only be terminated forcefully (with /F option).
ERROR: The process with PID 14188 (child process of PID 13384) could not be terminated.
Reason: This process can only be terminated forcefully (with /F option).
ERROR: The process with PID 13384 (child process of PID 5152) could not be terminated.
Reason: One or more child processes of this process were still running.

编辑4

我已将CreateNoWindow速度设置为false。 这使我可以用process.CloseMainWindow()关闭子应用程序,但是仍然没有其他方法可以工作(GenerateConsoleCtrlEvent,proc.StandardInput.WriteLine("\x3"),带有keybd_event的SendMessage,PostMessage)。

我被困住了。

0 个答案:

没有答案