如何用c#代码向控制台应用程序提供用户输入

本文关键字:用户 输入 应用程序 控制台 何用 代码 | 更新日期: 2023-09-27 18:09:29

我正在运行一个控制台应用程序exe(在c#中开发)由我的另一个windows应用程序在c#。

  Process p = Process.Start("strExePath");

我运行的控制台应用程序期望一些用户输入,我想通过运行控制台exe文件的windows应用程序的c#代码提供这些用户输入。我怎样才能做到这一点呢?

如何用c#代码向控制台应用程序提供用户输入

您可以重定向通过Process.Start()启动的控制台应用程序的标准输入。

为此,您需要使用ProcessStartInfo.RedirectStandardInput

在我链接的MSDN文档中有一个完整的示例。

另外,这里有一个包装器类,您可以根据自己的需要进行调整。(代码有点旧,所以它没有使用最新的c#功能,如Tasks,但希望它仍然会展示你需要做什么。)

注意,当您重定向输入和输出时,为了使I/O重定向工作没有死锁,必须使用一个单独的线程来处理I/O:

/// <summary>
/// Encapsulates an executable program.
/// This class makes it easy to run a console app and have that app's output appear
/// in the parent console's window, and to redirect input and output from/to files.
/// </summary>
/// <remarks>
/// To use this class:
/// (1) Create an instance.
/// (2) Set the ProgramFileName property if a filename wasn't specified in the constructor.
/// (3) Set other properties if required.
/// (4) Call Run().
/// </remarks>
public class Executable
{
    #region Constructor
    /// <summary>Constructor.</summary>
    /// <param name="programFileName">Name of the program file to run.</param>
    public Executable(string programFileName)
    {
        ProgramFileName = programFileName;
        _processStartInfo.ErrorDialog            = false;
        _processStartInfo.CreateNoWindow         = false;
        _processStartInfo.UseShellExecute        = false;
        _processStartInfo.RedirectStandardOutput = false;
        _processStartInfo.RedirectStandardError  = false;
        _processStartInfo.RedirectStandardInput  = false;
        _processStartInfo.WindowStyle            = ProcessWindowStyle.Hidden;
        _processStartInfo.Arguments              = "";
    }
    /// <summary>Construct with an empty executable name.</summary>
    public Executable(): this(string.Empty)
    {
    }
    #endregion  // Constructor
    #region Public Properties
    /// <summary>The filename (full pathname) of the executable.</summary>
    public string ProgramFileName
    {
        get
        {
            return _processStartInfo.FileName;
        }
        set
        {
            _processStartInfo.FileName = value;
        }
    }
    /// <summary> command-line arguments passed to the executable when run.</summary>
    public string Arguments
    {
        get
        {
            return _processStartInfo.Arguments;
        }
        set
        {
            _processStartInfo.Arguments = value;
        }
    }
    /// <summary> The working directory set for the executable when run. </summary>
    public string WorkingDirectory
    {
        get
        {
            return _processStartInfo.WorkingDirectory;
        }
        set
        {
            _processStartInfo.WorkingDirectory = value;
        }
    }
    /// <summary>
    /// The file to be used if standard input is redirected,
    /// or null or string.Empty to not redirect standard input.
    /// </summary>
    public string StandardInputFileName
    {
        set
        {
            _standardInputFileName = value;
            _processStartInfo.RedirectStandardInput = !string.IsNullOrEmpty(value);
        }
        get
        {
            return _standardInputFileName;
        }
    }
    /// <summary>
    /// The file to be used if standard output is redirected,
    /// or null or string.Empty to not redirect standard output.
    /// </summary>
    public string StandardOutputFileName
    {
        set
        {
            _standardOutputFileName = value;
            _processStartInfo.RedirectStandardOutput = !string.IsNullOrEmpty(value);
        }
        get
        {
            return _standardOutputFileName;
        }
    }
    /// <summary>
    /// The file to be used if standard error is redirected,
    /// or null or string.Empty to not redirect standard error.
    /// </summary>
    public string StandardErrorFileName
    {
        set
        {
            _standardErrorFileName = value;
            _processStartInfo.RedirectStandardError = !string.IsNullOrEmpty(value);
        }
        get
        {
            return _standardErrorFileName;
        }
    }
    #endregion  // Public Properties
    #region Public Methods
    /// <summary>Run the executable and wait until the it has terminated.</summary>
    /// <returns>The exit code returned from the executable.</returns>
    public int Run()
    {
        Thread standardInputThread  = null;
        Thread standardOutputThread = null;
        Thread standardErrorThread  = null;
        _standardInput  = null;
        _standardError  = null;
        _standardOutput = null;
        int exitCode = -1;
        try
        {
            using (Process process = new Process())
            {
                process.StartInfo = _processStartInfo;
                process.Start();
                if (process.StartInfo.RedirectStandardInput)
                {
                    _standardInput = process.StandardInput;
                    standardInputThread = startThread(new ThreadStart(supplyStandardInput), "StandardInput");
                }
                if (process.StartInfo.RedirectStandardError)
                {
                    _standardError = process.StandardError;
                    standardErrorThread = startThread(new ThreadStart(writeStandardError), "StandardError");
                }
                if (process.StartInfo.RedirectStandardOutput)
                {
                    _standardOutput = process.StandardOutput;
                    standardOutputThread = startThread(new ThreadStart(writeStandardOutput), "StandardOutput");
                }
                process.WaitForExit();
                exitCode = process.ExitCode;
            }
        }
        finally  // Ensure that the threads do not persist beyond the process being run
        {
            if (standardInputThread != null)
                standardInputThread.Join();
            if (standardOutputThread != null)
                standardOutputThread.Join();
            if (standardErrorThread != null)
                standardErrorThread.Join();
        }
        return exitCode;
    }
    #endregion  // Public Methods
    #region Private Methods
    private static Thread startThread(ThreadStart startInfo, string name)
    {
        Thread t = new Thread(startInfo);
        t.IsBackground = true ;
        t.Name = name;
        t.Start();
        return t;
    }
    /// <summary>Thread which supplies standard input from the appropriate file to the running executable.</summary>
    private void supplyStandardInput()
    {
        // feed text from the file a line at a time into the standard input stream
        // NOTE: THERE MAY BE ISSUES RELATED TO CHARACTER ENCODING HERE -- REQUIRES INVESTIGATION
        using (StreamReader reader = File.OpenText(_standardInputFileName))
        using (StreamWriter writer = _standardInput)
        {
            writer.AutoFlush = true;
            for (;;)
            {
                string textLine = reader.ReadLine();
                if (textLine == null)
                    break;
                writer.WriteLine(textLine);
            }
        }
    }
    /// <summary>Thread which outputs standard output from the running executable to the appropriate file.</summary>
    private void writeStandardOutput()
    {
        // NOTE: THERE MAY BE ISSUES RELATED TO CHARACTER ENCODING HERE -- REQUIRES INVESTIGATION
        using (StreamWriter writer = File.CreateText(_standardOutputFileName))
        using (StreamReader reader = _standardOutput)
        {
            writer.AutoFlush = true;
            for (;;)
            {
                string textLine = reader.ReadLine();
                if (textLine == null)
                    break;
                writer.WriteLine(textLine);
            }
        }
        if (File.Exists(_standardOutputFileName))
        {
            FileInfo info = new FileInfo(_standardOutputFileName);
            // if the error info is empty or just contains eof etc.
            if (info.Length < 4)
                info.Delete();
        }
    }
    /// <summary>Thread which outputs standard error output from the running executable to the appropriate file.</summary>
    private void writeStandardError()
    {
        // NOTE: THERE MAY BE ISSUES RELATED TO CHARACTER ENCODING HERE -- REQUIRES INVESTIGATION
        using (StreamWriter writer = File.CreateText(_standardErrorFileName))
        using (StreamReader reader = _standardError)
        {
            writer.AutoFlush = true;
            for (;;)
            {
                string textLine = reader.ReadLine();
                if (textLine == null)
                    break;
                writer.WriteLine(textLine);
            }
        }
        if (File.Exists(_standardErrorFileName))
        {
            FileInfo info = new FileInfo(_standardErrorFileName);
            // if the error info is empty or just contains eof etc.
            if (info.Length < 4)
                info.Delete();
        }
    }
    #endregion  // Private Methods
    #region Private Fields
    private StreamReader _standardError  ;
    private StreamReader _standardOutput ;
    private StreamWriter _standardInput  ;
    private string _standardInputFileName;
    private string _standardOutputFileName;
    private string _standardErrorFileName;
    ProcessStartInfo _processStartInfo = new ProcessStartInfo();
    #endregion  // Private Fields
}