c# - 在当前控制台运行进程

标签 c# process console

我正在为 Windows 编写一个基本的 shell,我想知道是否有任何方法可以运行子进程 (Process process) 以便它使用当前的控制台窗口。我的意思是我不想重定向输入/输出;我希望进程从当前控制台获取输入并将输出直接打印到同一控制台窗口。

原因是我想允许此子进程为输出设置控制台颜色,如果我重定向进程的标准输出则不会发生这种情况。另外,我目前使用代码

while (!process.HasExited)
    process.StandardInput.WriteLine(Console.ReadLine());

将标准输入重定向到进程。但是,如果进程在输入后立即退出(例如,我键入“exit”+ ENTER,然后进程退出),则此循环将再次运行,因此控制台正在等待用户永远不会使用的输入按进程(即将退出)

所以,长话短说,我如何在当前控制台中运行一个进程,以便它可以设置控制台颜色并直接从控制台获取输入

编辑:以下是我的代码中与此问题相关的方法:

static int runExe(string exePath, params string[] args)
{
    ProcessStartInfo startInfo = new ProcessStartInfo(exePath, args)
    {
        ErrorDialog = false,
        UseShellExecute = false,
        CreateNoWindow = true,
        RedirectStandardInput = true,
        RedirectStandardOutput = true,
        RedirectStandardError = true,
        RedirectStandardInput = true
    };
    Process process = new Process() { StartInfo = startInfo };
    process.Start();
    ReadThreadState stdout = readThread(process.StandardOutput, false);
    ReadThreadState stderr = readThread(process.StandardError, true);
    while (!process.HasExited)
        process.StandardInput.WriteLine(Console.ReadLine());
    stdout.stop = stderr.stop = true;
    return process.ExitCode;
}
class ReadThreadState
{
    public bool stop;
}
private static ReadThreadState readThread(StreamReader reader, bool isError)
{
    ReadThreadState state = new ReadThreadState();
    new Thread(() =>
    {
        while (!state.stop)
        {
            int current;
            while ((current = reader.Read()) >= 0)
                if (isError)
                    writeError(((char)current).ToString(), ConsoleColor.Red);
                else
                    Console.Write((char)current);
        }
    }).Start();
    return state;
}

最佳答案

您需要创建一个 ProcessStartInfo 并将 UseShellExecute 设置为 false:

var info = new ProcessStartInfo("program.exe", "arguments");
info.UseShellExecute = false;
var proc = Process.Start(info);
proc.WaitForExit();

这将在同一个控制台中启动您的程序。

使用上述技术的工作程序:

private static void Main(string[] args)
{
    Console.WriteLine("Starting program");
    var saveColor = Console.BackgroundColor;
    Console.BackgroundColor = ConsoleColor.Blue;
    var info = new ProcessStartInfo("cmd", "/c time");
    info.UseShellExecute = false;
    var proc = Process.Start(info);
    proc.WaitForExit();

    Console.BackgroundColor = saveColor;
    Console.WriteLine("Program exited");
    Console.ReadLine();
}

当您运行该程序时,它会启动一个新的 cmd.exe 副本并运行 time 命令,该命令要求输入。这里我只是以cmd.exe为例进行说明。任何从标准输入读取的程序都可以工作。另请注意,控制台颜色可以正常工作。

关于c# - 在当前控制台运行进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17751860/

相关文章:

c# - 如何将运行时参数传递给 ViewComponent Invoke 方法

c# - HDInsight模拟器-如何基于C#可执行文件在本地运行MapReduce作业

android - 在 Android 中杀死根进程

c - 在 OSX 中从控制台读取输入

ruby-on-rails - puts 不打印东西到控制台

node.js - NodeJs 击键在控制台中打印两次

c# - 如何从 Xamarin 中的 android 项目访问文件

c# - Akavache 无效

multithreading - 像特斯拉的 AutoPilot 这样的系统如何跟上不断变化的多进程请求?

检查子进程是否在 Unix 上的 C 中终止而没有阻塞