我想在某处重定向cmd.exe输出,当命令是一行时,下面的代码可以工作:
Process p = new Process()
{
StartInfo = new ProcessStartInfo("cmd")
{
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
Arguments = String.Format("/c \"{0}\"", command),
}
};
p.OutputDataReceived += (s, e) => Messagebox.Show(e.Data);
p.Start();
p.BeginOutputReadLine();
p.WaitForExit();
但是像WriteLine()这样的系列命令怎么样:
p.StandardInput.WriteLine("cd...");
p.StandardInput.WriteLine("dir");
如何在这种情况下获得输出?
答案 0 :(得分:4)
要实现此类行为,您应该使用/k
开关以交互模式运行cmd.exe
。
问题是将输入与不同的命令分开。
为此,您可以使用prompt
命令更改标准提示:
prompt --Prompt_C2BCE8F8E2C24403A71CA4B7F7521F5B_F659E9F3F8574A72BE92206596C423D5
所以现在很容易确定命令输出的结束。
以下是完整的代码:
public static IEnumerable<string> RunCommands(params string[] commands) {
var process = new Process {
StartInfo = new ProcessStartInfo("cmd") {
UseShellExecute = false,
RedirectStandardInput = true,
RedirectStandardOutput = true,
CreateNoWindow = true,
Arguments = "/k",
}
};
process.Start();
const string prompt = "--Prompt_C2BCE8F8E2C24403A71CA4B7F7521F5B_F659E9F3F8574A72BE92206596C423D5 ";
// replacing standard prompt in order to determine end of command output
process.StandardInput.WriteLine("prompt " + prompt);
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
process.StandardOutput.ReadLine();
var result = new List<string>();
try {
var commandResult = new StringBuilder();
foreach (var command in commands) {
process.StandardInput.WriteLine(command);
process.StandardInput.WriteLine();
process.StandardInput.Flush();
process.StandardOutput.ReadLine();
while (true) {
var line = process.StandardOutput.ReadLine();
if (line == prompt) // end of command output
break;
commandResult.AppendLine(line);
}
result.Add(commandResult.ToString());
commandResult.Clear();
}
} finally {
process.Kill();
}
return result;
}
效果很好,但看起来像是一个大黑客。
我建议你改用每个命令的进程。