在当前控制台中运行进程
我正在为Windows编写一个基本的shell,我想知道是否有任何方法可以运行子Process process
( 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为例来说明。 从标准输入读取的任何程序都可以使用。 另请注意,控制台颜色正常工作。
Jim Mischel的回答就像一个魅力。 我正在将一些批处理文件处理转移到C#中,这很有效。 你可能会发现这个小实用方法很方便。 只需要一个命令行,然后像批处理文件中的CALL一样运行它。 只需将它填入实用程序类:
public static void RunCmd(string command) { Process.Start(new ProcessStartInfo("cmd.exe", "/c " + command) { UseShellExecute = false }).WaitForExit(); }