在c#中重定向stdout的问题

时间:2010-06-16 08:29:51

标签: c# .net

您能解释为什么shell重定向不能与System.Diagnostics.Process类一起使用吗?我正在尝试使用以下代码段将输出流重定向到文件:

Process p = new Process();
p.StartInfo = new ProcessStartInfo();
p.StartInfo.FileName = "java.exe";
p.StartInfo.Arguments = @"> c:\Temp\test.log 2>&1";
p.StartInfo.UseShellExecute = true;
p.Start();

类似的代码可以正常使用Python。 在我的情况下,以编程方式读取输出流似乎不是一个更好的解决方案,因为我的应用程序将启动一系列进程。

3 个答案:

答案 0 :(得分:3)

这是因为没有shell来处理这些参数。 当您键入命令行到shell时,它会被解析,程序参数与shell“特殊”修饰符分开,然后才会启动。 在C#中,这不会发生,因为没有“cmd.exe”或“bash”进程来执行此操作。

要在C#中重定向输入,您应将p.StartInfo.RedirectStandardOutput设置为true,然后使用p.StandardOutput读取数据,然后将其写入文件。

或者,您可以运行“cmd.exe”,其中包含执行该过程所需的参数并重定向其输出。虽然不是跨平台的,但这比编写高效的数据流传递实现更容易。

答案 1 :(得分:2)

您无法执行重定向,因为没有直接涉及shell。您可以运行cmd.exe会话,但正确的方法是使用RedirectStandardOutput / Error属性。有很多进程时没有问题。这是我用来做的一个课程。

    class HandleExecutable {
        private DataReceivedEventHandler outputHandler;

        public DataReceivedEventHandler OutputHandler
        {
            set { outputHandler = value; }
        }
        private DataReceivedEventHandler errorHandler;

        public DataReceivedEventHandler ErrorHandler
        {
            set { errorHandler = value; }
        }

        public void callExecutable(string executable, string args)
        {
            string commandLine = executable;
            string args = args;
            ProcessStartInfo psi = new ProcessStartInfo(commandLine);
            psi.UseShellExecute = false;
            psi.LoadUserProfile = false;
            psi.RedirectStandardOutput = true;
            psi.RedirectStandardError = true;
            psi.WindowStyle = ProcessWindowStyle.Minimized;
            psi.CreateNoWindow = true;
            psi.Arguments = args;
            p = new Process();
            p.StartInfo = psi;
            try
            {
                p.Start();
                p.BeginOutputReadLine();
                p.BeginErrorReadLine();
                if (outputHandler != null) p.OutputDataReceived += outputHandler;
                if (errorHandler != null) p.ErrorDataReceived += errorHandler;
                p.WaitForExit();
                p.Close();
                p.Dispose();
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }
        }
    }

    //On another class
    void p_ErrorDataReceived(object sender, DataReceivedEventArgs e)
    {
        //HANDLE STDERR
        if (e.Data != null && !e.Data.Equals(""))
        {
             if (!e.Data.Contains("Something")) {
             }
        }
    }

    void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        //HANDLE STDOUT
        if (e.Data != null && !e.Data.Equals(""))
        {
        }
    }

    HandleExecutable he = new HandleExecutable();
    he.OutputHandler = p_OutputDataReceived;
    he.ErrorHandler = p_ErrorDataReceived;
    he.callExecutable(@"C:\java.exe","-cp foo ClassName");

答案 2 :(得分:0)

如果要重定向输出流,则必须对其进行配置。设置Redirect...属性并读取流。您可以找到示例here

此致