2013-02-21 1 views
6

Come Vim: quando si avvia, ti porta in un altro "buffer". Quando si chiude vim, l'utente vede il contenuto precedente del prompt dei comandi.Come eseguire un'applicazione C# Windows Console che "rispetta" il contenuto della console precedente?

Qualcuno sa come farlo usando C#?

Grazie

Edit: l'utente non sarebbe più vedere l'output dell'applicazione. Spero che lo spieghi meglio.

+1

L'esempio che viene descritto è come un'applicazione di console C# funzionerebbe attualmente se richiamata da una riga di comando; se si esegue un'app console, quindi si chiude, si torna alla riga di comando precedente. O mi sta sfuggendo qualcosa? – Dutts

+0

Penso che il poster significhi che qualsiasi output dell'app non dovrebbe più essere sulla console, ma piuttosto cosa c'era prima dell'esecuzione. – Matt

+0

@Richard Applicazioni come dir o cat verranno visualizzate sullo stesso "buffer" della console. Applicazioni come vim ridisegnano molto testo nella finestra della console, ma dopo averlo chiuso, l'utente torna a vedere i comandi digitati, incluso vim. Tutto l'output che vim ha messo sulla finestra è sparito. Fammi sapere se non mi sto spiegando correttamente – robertoprs

risposta

4

ho capito questo, cercando in Vim source code i bit rilevanti possono essere trovati in os_win32.c nella funzione mch_init, ho 'Ho copiato e incollato il bit in questione qui

/* 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 

Così salva semplicemente le informazioni della console (tra cui il titolo e l'icona) e quindi ripristina nuovamente in uscita.

Sfortunatamente la classe Console non fornisce accesso al contenuto del buffer dello schermo, per fare ciò è necessario P/Invoke nelle relative funzioni Win32.

In alternativa, il console Win32 supporta in realtà multiple screen buffers che potrebbe essere un modo più semplice per implementare questo - invece di copiare il buffer dello schermo esistente è sufficiente creare una nuova con la CreateConsoleScreenBuffer e impostare tale buffer di essere quello attualmente mostrato utilizzando SetConsoleActiveScreenBuffer. Anche in questo caso la classe Console non supporta più buffer di schermate, quindi è necessario P/Invoke per farlo. Anche la classe Console scrive sempre sul buffer dello schermo che era attivo nel punto in cui è stata lanciata l'applicazione, quindi se si sostituisce il buffer dello schermo attivo la classe Console continuerà a scrivere sul vecchio buffer dello schermo (che non è più visibile) - per ovviare a questo è necessario P/Richiamare tutto l'accesso alla console, vedere Working with Console Screen Buffers in .NET.

+0

Grazie! Hai ragione, avrei dovuto guardare il codice. Ho dimenticato che alcuni progetti sono ancora open source anche nel mondo Windows. Mi sono imbattuto in CreateConsoleScreenBuffer grazie alla risposta di jgauffin, ma salvare lo stato del buffer precedente è una grande idea! – robertoprs

+1

È necessario salvare il contenuto del buffer originale, poiché viene cancellato quando il buffer non è attivo. – robertoprs

-3

Credo che Vim registri la cronologia dei file aperti e molto probabilmente li buffer anche, come una copia di backup. L'idea di fare lo stesso in C# è di implementare un buffer di file, una sorta di archivio che registra e tiene traccia delle cose che vuoi - parametri di input, ecc.

Un altro problema qui è che Vim (come Vi) ha modalità di comando che sarebbe necessario implementare anche in C#. Ora questo dipende da cosa esattamente vuoi ottenere con il tuo programma C#, è un editor, quindi va bene, in ogni caso devi distinguere tra comando e altre modalità.

+1

Questo ha molto poco a che fare con la domanda. – hvd

+0

Credo che la domanda dell'OP sia stata un po 'colpita nel buio - non è facile da capire. Ho risposto a quello che pensavo fosse corretto. –

+1

La domanda ha senso per me. Apri un prompt dei comandi. Inizia vim. Osserva come appare vim nella stessa finestra. Uscita vim. Nota come nessun bit di Vim rimane visibile. Ora la domanda è come ottenerlo lavorando da C#. – hvd

0

Puoi farlo scrivendo vecchi contenuti nel buffer di console come descritto qui: How can I write fast colored output to Console?

+0

.. come stai proponendo di ottenere il vecchio contenuto? –

+0

Ho svalutato questo perché l'ho trovato utile. Non sapevo di PInvoke quindi non ero a conoscenza che potrei chiamare API Win32 dal codice C#. Grazie a questo ho trovato CreateConsoleScreenBuffer. La risposta di Justin è più dettagliata, ma questo è stato sufficiente per sbloccarmi. – robertoprs