【发布时间】:2013-07-19 17:12:59
【问题描述】:
我正在为 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;
}
【问题讨论】:
-
尝试使用
cmd.exe的/c选项。喜欢Process.Start("cmd.exe", "YOURAPP.exe /c"); -
@Anri 我不认为那是我需要的;我不想通过
cmd.exe运行它。 -
通过 cmd 启动控制台应用程序几乎没有区别
-
这个要求有点危险。这意味着另一个应用程序可能应该是您在程序中引用的 .dll,而不是另一个可执行程序。
-
@Servy 我正在编写一个有颜色的命令外壳。如果我从 shell 中键入“shell” ENTER,则子 shell 没有颜色。我想要它。但是,我不能为 shell 将运行的每个程序引用每个 .dll;有些程序甚至可能不是 .NET 程序...