2013-02-21 26 views
6

和Vim一樣:當它啓動時會帶你到另一個「緩衝區」。當vim關閉時,用戶將看到命令提示符的先前內容。如何做一個「尊重」以前的控制檯內容的C#Windows控制檯應用程序?

有誰知道如何使用C#做到這一點?

謝謝

編輯:用戶將不會再看到應用程序的輸出。希望能更好地解釋它。

+1

您描述的示例是如果從命令行調用C#控制檯應用程序當前將如何工作;如果您執行一個控制檯應用程序,然後關閉它,您將返回到您的上一個命令行。或者我錯過了什麼? – Dutts 2013-02-21 08:33:38

+0

我認爲海報意味着應用程序的任何輸出都不應該放在控制檯上,而應該放在執行之前。 – Matt 2013-02-21 08:37:19

+0

@Richard像dir或cat這樣的應用程序會在同一個控制檯「緩衝區」上噴出。像vim這樣的應用程序會在控制檯窗口上重新繪製大量文本,但在關閉它之後,用戶又會看到他或她輸入的命令,包括vim。 vim放在窗口上的所有輸出都消失了。讓我知道如果我不正確地解釋我自己 – robertoprs 2013-02-21 08:39:36

回答

4

我想通了這一點通過查看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

+0

謝謝!你是對的,我應該看看代碼。即使在Windows世界,我忘記了一些項目仍然是開源的。 由於jgauffin的回答,我碰到了CreateConsoleScreenBuffer,但是保存前一個緩衝區的狀態是個好主意! – robertoprs 2013-02-21 15:56:44

+1

原因是保存原始緩衝區內容是必要的,因爲當緩衝區未激活時它被清除。 – robertoprs 2013-02-22 07:40:33

-3

我相信Vim會記錄它的打開文件的歷史記錄,並且很可能它會緩衝它們,就像備份副本一樣。在C#中執行相同的想法是實現一個文件緩衝區,某種類型的存儲器,它可以記錄並跟蹤所需的內容 - 輸入參數等。

此處的另一個問題是Vim(如Vi)具有命令模式,這也需要在C#中實現。現在這取決於你想要用你的C#程序完成什麼,這是一個編輯器,那麼很好,無論如何,你必須區分命令和其他模式。

+1

這與問題很少有關。 – hvd 2013-02-21 08:44:56

+0

我相信OP的問題在黑暗中有點打擊 - 根本不容易理解。我回答了我認爲是正確的。 – 2013-02-21 08:50:49

+1

這個問題對我有意義。打開命令提示符。啓動vim。注意vim如何在同一個窗口中出現。退出vim。注意vim中的任何位都不可見。現在的問題是如何從C#開始工作。 – hvd 2013-02-21 08:53:58

0

您可以通過編寫舊的內容到控制檯緩衝區這裏描述做到這一點:How can I write fast colored output to Console?

+0

..你如何提出獲取舊內容? – 2013-02-21 12:34:58

+0

我提高了這個,因爲我發現它很有用。我不知道PInvoke,所以我不知道我可以從C#代碼調用Win32 API。感謝這一點,我找到了CreateConsoleScreenBuffer。賈斯汀的回答更加詳細,但這足以打開我的視線。 – robertoprs 2013-02-21 16:03:14

相關問題