如何修改前一行控制台文本?

我想实现这样的目标:

Time consuming operation...OK Another time consuming operation... And another one, but it completed, so...OK 

我显示了3行文本,每行都与一个可以迟早结束的post相关。 但如果第二个比第三个完成,我会得到这样的东西:

 Time consuming operation...OK Another time consuming operation... And another one, but it completed, so...OKOK 

这当然是不可接受的。 我知道如何回到目前的路线,但有没有办法上线? 我发誓我已经在某个地方见过它,虽然它可能是一个Linux控制台:)

算了吧。 见远程文件管理器! 它适用于Windows控制台,甚至可以在PowerShell中运行! 如何制作这样的东西? 最酷的部分是退出后恢复控制台状态。 所以也许我应该问 – 如何直接访问控制台缓冲区? 我假设我需要一些本机代码来完成这个技巧,但也许还有另外一种方法呢? 我想到每次更新清除控制台,但这似乎有点矫枉过正。 或许它不是? 它会眨眼吗?

您可以将光标移动到任何位置: Console.SetCursorPosition或使用Console.CursorTop 。

 Console.SetCursorPosition(0, Console.CursorTop -1); Console.WriteLine("Over previous line!!!"); 

使用回车。 此示例打印一行,覆盖之前的内容。

  Console.WriteLine(); for (int i = 0; i <= 100; i++) { System.Threading.Thread.Sleep(10); Console.Write("\x000DProgress: " + i); } 

只要您的所有字符串少于80列 (或者您的终端缓冲区设置为任何列),这都可以正常工作。

注意:以下答案最初是由OP编写的。


这是完整的演示解决方案:

 using System; using System.Collections.Generic; using System.Threading; namespace PowerConsole { internal class Containers { internal struct Container { public int Id; public int X; public int Y; public string Content; } public static List Items = new List(); private static int Identity = 0; public static int Add(string text) { var c = new Container(); c.Id = Identity++; cX = Console.CursorLeft; cY = Console.CursorTop; c.Content = text; Console.Write(text); Items.Add(c); return c.Id; } public static void Remove(int id) { Items.RemoveAt(id); } public static void Replace(int id, string text) { int x = Console.CursorLeft, y = Console.CursorTop; Container c = Items[id]; Console.MoveBufferArea( cX + c.Content.Length, cY, Console.BufferWidth - cX - text.Length, 1, cX + text.Length, cY ); Console.CursorLeft = cX; Console.CursorTop = cY; Console.Write(text); c.Content = text; Console.CursorLeft = x; Console.CursorTop = y; } public static void Clear() { Items.Clear(); Identity = 0; } } internal class Program { private static List Threads = new List(); private static void Main(string[] args) { Console.WriteLine("So we have some threads:\r\n"); int i, id; Random r = new Random(); for (i = 0; i < 10; i++) { Console.Write("Starting thread " + i + "...["); id = Containers.Add("?"); Console.WriteLine("]"); Thread t = new Thread((object data) => { Thread.Sleep(r.Next(5000) + 100); Console.ForegroundColor = ConsoleColor.Green; Containers.Replace((int)data, "DONE"); Console.ResetColor(); }); Threads.Add(t); } Console.WriteLine("\n\"But will it blend?\"..."); Console.ReadKey(true); i = 0; Threads.ForEach(t => t.Start(i++)); Threads.ForEach(t => t.Join()); Console.WriteLine("\r\nVoila."); Console.ReadKey(true); } } }