和Vim一樣:當它啓動時會帶你到另一個「緩衝區」。當vim關閉時,用戶將看到命令提示符的先前內容。如何做一個「尊重」以前的控制檯內容的C#Windows控制檯應用程序?
有誰知道如何使用C#做到這一點?
謝謝
編輯:用戶將不會再看到應用程序的輸出。希望能更好地解釋它。
和Vim一樣:當它啓動時會帶你到另一個「緩衝區」。當vim關閉時,用戶將看到命令提示符的先前內容。如何做一個「尊重」以前的控制檯內容的C#Windows控制檯應用程序?
有誰知道如何使用C#做到這一點?
謝謝
編輯:用戶將不會再看到應用程序的輸出。希望能更好地解釋它。
我想通了這一點通過查看Vim source code相關的位可以os_win32.c在mch_init
功能被發現,我「VE複製並粘貼在這裏的相關位
/* Obtain handles for the standard Console I/O devices */
if (read_cmd_fd == 0)
g_hConIn = GetStdHandle(STD_INPUT_HANDLE);
else
create_conin();
g_hConOut = GetStdHandle(STD_OUTPUT_HANDLE);
#ifdef FEAT_RESTORE_ORIG_SCREEN
/* Save the initial console buffer for later restoration */
SaveConsoleBuffer(&g_cbOrig);
g_attrCurrent = g_attrDefault = g_cbOrig.Info.wAttributes;
#else
/* Get current text attributes */
GetConsoleScreenBufferInfo(g_hConOut, &csbi);
g_attrCurrent = g_attrDefault = csbi.wAttributes;
#endif
if (cterm_normal_fg_color == 0)
cterm_normal_fg_color = (g_attrCurrent & 0xf) + 1;
if (cterm_normal_bg_color == 0)
cterm_normal_bg_color = ((g_attrCurrent >> 4) & 0xf) + 1;
/* set termcap codes to current text attributes */
update_tcap(g_attrCurrent);
GetConsoleCursorInfo(g_hConOut, &g_cci);
GetConsoleMode(g_hConIn, &g_cmodein);
GetConsoleMode(g_hConOut, &g_cmodeout);
#ifdef FEAT_TITLE
SaveConsoleTitleAndIcon();
/*
* Set both the small and big icons of the console window to Vim's icon.
* Note that Vim presently only has one size of icon (32x32), but it
* automatically gets scaled down to 16x16 when setting the small icon.
*/
if (g_fCanChangeIcon)
SetConsoleIcon(g_hWnd, g_hVimIcon, g_hVimIcon);
#endif
所以它只是保存控制檯的信息(包括標題和圖標),然後再恢復它退出。
不幸的是Console
類沒有提供對屏幕緩衝區內容的訪問,所以要做到這一點,你需要將P/Invoke調入相關的Win32函數。
或者在Win32控制檯實際上支持multiple screen buffers這可能是實現這個更簡單的方法 - 而不是複製現有的屏幕緩衝區只需要創建一個新的使用CreateConsoleScreenBuffer
並設置緩衝區是使用SetConsoleActiveScreenBuffer
目前所示。不幸的是,Console
類不幸的是不支持多個屏幕緩衝區,因此您需要P/Invoke來完成此操作。此外,Console
類總是寫入啓動應用程序時處於活動狀態的屏幕緩衝區,所以如果換出活動屏幕緩衝區,Console
類仍會寫入舊屏幕緩衝區(不再可見) - 要解決這個問題,您需要P/Invoke您的所有控制檯訪問權限,請參閱Working with Console Screen Buffers in .NET。
謝謝!你是對的,我應該看看代碼。即使在Windows世界,我忘記了一些項目仍然是開源的。 由於jgauffin的回答,我碰到了CreateConsoleScreenBuffer,但是保存前一個緩衝區的狀態是個好主意! – robertoprs 2013-02-21 15:56:44
原因是保存原始緩衝區內容是必要的,因爲當緩衝區未激活時它被清除。 – robertoprs 2013-02-22 07:40:33
我相信Vim會記錄它的打開文件的歷史記錄,並且很可能它會緩衝它們,就像備份副本一樣。在C#中執行相同的想法是實現一個文件緩衝區,某種類型的存儲器,它可以記錄並跟蹤所需的內容 - 輸入參數等。
此處的另一個問題是Vim(如Vi)具有命令模式,這也需要在C#中實現。現在這取決於你想要用你的C#程序完成什麼,這是一個編輯器,那麼很好,無論如何,你必須區分命令和其他模式。
您可以通過編寫舊的內容到控制檯緩衝區這裏描述做到這一點:How can I write fast colored output to Console?
..你如何提出獲取舊內容? – 2013-02-21 12:34:58
我提高了這個,因爲我發現它很有用。我不知道PInvoke,所以我不知道我可以從C#代碼調用Win32 API。感謝這一點,我找到了CreateConsoleScreenBuffer。賈斯汀的回答更加詳細,但這足以打開我的視線。 – robertoprs 2013-02-21 16:03:14
您描述的示例是如果從命令行調用C#控制檯應用程序當前將如何工作;如果您執行一個控制檯應用程序,然後關閉它,您將返回到您的上一個命令行。或者我錯過了什麼? – Dutts 2013-02-21 08:33:38
我認爲海報意味着應用程序的任何輸出都不應該放在控制檯上,而應該放在執行之前。 – Matt 2013-02-21 08:37:19
@Richard像dir或cat這樣的應用程序會在同一個控制檯「緩衝區」上噴出。像vim這樣的應用程序會在控制檯窗口上重新繪製大量文本,但在關閉它之後,用戶又會看到他或她輸入的命令,包括vim。 vim放在窗口上的所有輸出都消失了。讓我知道如果我不正確地解釋我自己 – robertoprs 2013-02-21 08:39:36