简体   繁体   English

重定向的批处理文件进程输出未运行

[英]Redirected batch file process output not running

I'm attempting to redirect output from a batch file execution to the main window of our console application. 我试图将输出从批处理文件执行重定向到控制台应用程序的主窗口。

I'm calling the method to run the process like this: 我正在调用方法来像这样运行过程:

this.runProcess("\\bar\foo\blah\", "myBatch1.bat", "bat");

The method being called is as follows: 调用的方法如下:

public void runProcess(string aPath,string aName,string aFiletype)
{

  Console.WriteLine();
  Console.WriteLine();
  Console.WriteLine("Started: {0}",DateTime.Now.ToString("dd-MMM hh:mm:ss"));
  Console.WriteLine("Will try run this file {0} {1}",aPath,aName);
  Console.WriteLine("File type {0}",aFiletype);

  string stInfoFileName;
  string stInfoArgs;

  if(aFiletype == "bat")
  {
    stInfoFileName = @"cmd.exe";
    stInfoArgs = "//c " + aName;
  }
  else
  { //vbs
    stInfoFileName = @"cscript";
    stInfoArgs = "//B " + aName;
  }

  this.aProcess.StartInfo.FileName = stInfoFileName;
  this.aProcess.StartInfo.Arguments =  stInfoArgs;
  this.aProcess.StartInfo.WorkingDirectory = @aPath;
  this.aProcess.StartInfo.CreateNoWindow = true;
  this.aProcess.StartInfo.UseShellExecute = false;
  this.aProcess.StartInfo.RedirectStandardError = true;
  this.aProcess.StartInfo.RedirectStandardOutput = true;

  this.aProcess.Start();
  Console.WriteLine("<<<got to here");

  Console.WriteLine(this.aProcess.StandardOutput.ReadToEnd());
  Console.WriteLine(this.aProcess.StandardError.ReadToEnd());

  this.aProcess.WaitForExit(); //<-- Optional if you want program running until your script exit
  this.aProcess.Close();

  Console.WriteLine("Finished: {0}",DateTime.Now.ToString("dd-MMM hh:mm:ss"));
}

To try to figure out what is happening I've added extra calls to WriteLine . 为了弄清楚正在发生什么,我向WriteLine添加了额外的调用。
"<<<got to here" gets written to the console then it just hangs and nothing further happens. "<<<got to here"被写入控制台,然后挂起,没有任何进一步的反应。

Suspect my mistake is something very trivial as my experience with this technology is limited. 怀疑我的错误非常琐碎,因为我对这项技术的经验有限。

What am I doing wrong? 我究竟做错了什么?

Well, you're using ReadToEnd() - that's going to block until the process exits, basically. 好吧,您正在使用ReadToEnd() -它将阻塞直到基本上退出该过程。

This is an exceptionally bad idea when you're redirecting both Standard Output and Error - when the I/O buffer gets full, both of the applications are going to freeze. 当您同时重定向标准输出和错误时,这是​​一个非常糟糕的主意-当I / O缓冲区已满时,两个应用程序都将冻结。

Instead, you might want to use asynchronous I/O to read the output (and write it to console as needed - you'll need to make sure the Error and Output don't mess each other up, though). 相反,您可能想使用异步I / O读取输出(并根据需要将其写入控制台-您需要确保Error和Output不会互相搞乱)。 Or just redirect either one of those rather than both. 或者只是重定向其中一个而不是两个。

The easiest way to handle this is by using ErrorDataReceived and OutputDataReceived events: 解决此问题的最简单方法是使用ErrorDataReceivedOutputDataReceived事件:

aProcess.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
aProcess.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);

aProcess.BeginOutputReadLine();
aProcess.BeginErrorReadLine();

aProcess.WaitForExit();

Apart from actually working, this also means that the output is printed out as it comes, rather than when the process exits. 除了实际工作之外,这还意味着输出将在输出时打印出来,而不是在过程退出时输出。

Since you want the child's output in the existing console, you don't need any redirection. 由于您希望孩子在现有控制台中进行输出,因此不需要任何重定向。 Just set UseShellExecute to false and don't set CreateNoWindow . 只需将UseShellExecute设置为false,而不设置CreateNoWindow

This code works for me: 该代码对我有用:

using System;
using System.Diagnostics;

namespace ConsoleApplication1
{
    class Program
    {
        Process aProcess = new Process();

        public void runProcess(string aPath, string aName, string aFiletype)
        {
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Started: {0}", DateTime.Now.ToString("dd-MMM hh:mm:ss"));
            Console.WriteLine("Will try run this file {0} {1}", aPath, aName);
            Console.WriteLine("File type {0}", aFiletype);

            string stInfoFileName;
            string stInfoArgs;

            if (aFiletype == "bat")
            {
                stInfoFileName = "cmd.exe";
                stInfoArgs = "/c " + aPath + aName;
            }
            else
            { //vbs
                stInfoFileName = "cscript";
                stInfoArgs = "/B " + aPath + aName;
            }

            this.aProcess.StartInfo.FileName = stInfoFileName;
            this.aProcess.StartInfo.Arguments = stInfoArgs;
            this.aProcess.StartInfo.WorkingDirectory = aPath;
            this.aProcess.StartInfo.UseShellExecute = false;

            this.aProcess.Start();

            Console.WriteLine("<<<got to here");

            this.aProcess.WaitForExit(); //<-- Optional if you want program running until your script exit
            this.aProcess.Close();

            Console.WriteLine("Finished: {0}", DateTime.Now.ToString("dd-MMM hh:mm:ss"));
        }

        static void Main(string[] args)
        {
            new Program().runProcess("c:\\working\\", "test.bat", "bat");
            Console.WriteLine("Exiting");
        }
    }
}

I took out the redirection and associated logic, and the line that set CreateNoWindow . 我取出了重定向和相关的逻辑,以及设置CreateNoWindow I also added aPath to the command line so that it would work for UNC paths (paths with no drive letter) since they can't be set as the working directory. 我还向命令行添加了aPath ,以便它可以用于UNC路径(没有驱动器号的路径),因为它们不能设置为工作目录。

I amended the first option after if(aFiletype == "bat") and the bat files are running ok. 我修改了if(aFiletype == "bat")之后的第一个选项,并且bat文件运行正常。

public void runProcess(string aPath,string aName,string aFiletype)
{
  aProcess = new Process();

  Console.WriteLine();
  Console.WriteLine();
  Console.WriteLine("Started: {0}",DateTime.Now.ToString("dd-MMM hh:mm:ss"));
  Console.WriteLine("Will try run this file {0} {1}",aPath,aName);
  Console.WriteLine("File type {0}",aFiletype);

  string stInfoFileName;
  string stInfoArgs;

  if(aFiletype == "bat")
  {
    stInfoFileName = (@aPath + @aName);
    stInfoArgs = string.Empty;
  }
  else
  { //vbs
    stInfoFileName = @"cscript";
    stInfoArgs = "//B " + aName;
  }

  this.aProcess.StartInfo.FileName = stInfoFileName;
  this.aProcess.StartInfo.Arguments =  stInfoArgs;

  this.aProcess.StartInfo.WorkingDirectory = @aPath;

  //new 18 june 2015//////
  if(aFiletype == "bat")
  {
    this.aProcess.StartInfo.CreateNoWindow = true;
    this.aProcess.StartInfo.UseShellExecute = false;
    this.aProcess.StartInfo.RedirectStandardError = true;     //<< HJ
    this.aProcess.StartInfo.RedirectStandardOutput = true;    //<< HJ
  }
  ////////////////////////

  this.aProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal; //.Hidden
  this.aProcess.Start();

  aProcessName = this.aProcess.ProcessName;
  if(aFiletype == "bat")
  {
    this.aProcess.ErrorDataReceived += (s,e) => Console.WriteLine(e.Data);
    this.aProcess.OutputDataReceived += (s,e) => Console.WriteLine(e.Data);
    this.aProcess.BeginOutputReadLine();
    this.aProcess.BeginErrorReadLine();
  }

  this.aProcess.WaitForExit();
  this.aProcess.Dispose();

Console.WriteLine("Process {0} closed: {1}", this.aProcessName, DateTime.Now.ToString("dd-MMM hh:mm:ss"));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 运行批处理文件,获取错误并将处理结果输出到文本文件中 - running batch file, getting error and process output into a text file 运行进程openfiles将结果输出到文件 - Running process openfiles output result to file 无法启动进程 do.net.exe - 输入或 output 无法重定向,因为指定的文件无效 - unable to start process dotnet.exe - input or output cannot be redirected because the specified file is invalid C#进程运行用于搅拌器导出的批处理文件被暂停 - c# process that running a batch file for blender exporting gets paused 在.NET中使用重定向的文件路径运行进程 - Run a Process with Redirected File Paths in .NET 在C#中运行批处理文件时捕获所有输出 - Capture ALL output when running batch file in c# 控制台 output(标准和错误)未重定向到文件 - Console output (standard and error) is not redirected to a file C#process.Kill不会立即停止正在运行批处理文件的进程 - C# process.Kill does not immediately stop a process that is running a batch file 在 C# 应用程序中获取重定向的进程输出到字符串中 - Get redirected process output into string in C# application C# - 处理重定向输出 - 与CMD窗口不同的控制台 - C# - Process redirected output - Console different to CMD window
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM