0

我想启动一个 cmd 文件并立即获得输出。

看我的代码。指令process.WaitForExit()不等待;为什么不? copyf.cmd如果我不以隐藏模式启动它,它运行良好,因为显示的 dosbox 运行到 cmd 的末尾。在隐藏模式下,cmd 关闭,因为process.WaitForExit()在 cmd 完成之前不要等待。

public void doSomeThing(   Queue<string> output, // queue for output log
                        Queue<string> error   // queue for error log
                       )  
{
            String com = "some params";

            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.FileName = Properties.Settings.Default.pathTo + @"\Make\copyf.cmd";
            startInfo.Arguments = com;
            startInfo.RedirectStandardOutput = true;
            startInfo.RedirectStandardError = true;
            startInfo.UseShellExecute = false;
            startInfo.CreateNoWindow = true;
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            process.StartInfo = startInfo;

            Thread thread = new Thread(new ThreadStart(() =>
            {
                String er;
                String outp;

                while (true)
                {
                    outp = process.StandardOutput.ReadLine();

                    if(outp != null)
                        output.Enqueue("Output :" + outp + "\n");

                    er = process.StandardError.ReadLine();
                    if (er != null)
                        error.Enqueue("Error :" + er + "\n");
                }
            }));

            process.Start();
            thread.Start();
            process.WaitForExit();
}
4

1 回答 1

0

您应该使用 C 开关启动实际的控制台命令处理器“cmd.exe”,而不是调用 .CMD 文件。

/Cswitch 将保持cmd.exe进程保持,直到您的命令文件完成执行。WaitForExit()将等到 CMD.exe 也完成执行。我已经用过很多次了。为了 WaitForExit 的正确操作,必须在 StandardError.ReadToEnd(); 之后调用它。如此处所述的 msdn修改版本发布如下:

    string command = string.Format("{0}\\Make\\copyf.cmd {1}", Properties.Settings.Default.pathTo , com);
    int waitTime = 60000; //1 min as example here
    using (var process = new Process()
    {
        StartInfo = new ProcessStartInfo()
                {
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    CreateNoWindow = true,
                    RedirectStandardInput = true,
                    RedirectStandardError = true,
                    FileName = "cmd.exe",
                    Arguments = string.Format("/C \"{0}\"", command)
                }
    })
    {
        try
        {
            if (!process.Start())
            {
                //Log some error "Failed to run command";
            }
        }
        catch (Exception ex)
        {
            //Log some error "Failed to start process command";
        }

        process.BeginOutputReadLine();
        string error = process.StandardError.ReadToEnd();
        process.WaitForExit(waitTime);
        if (!process.HasExited)
        {
            //Log something "Command: did not finish in time, terminating process"
            try
            {
                process.Kill();
            }
            catch { }
        }   
    }
于 2013-04-22T00:24:31.783 回答