20

I have written a console application, which is essentially a Console.ReadLine()-Loop. When the application is waiting for input, pressing the up arrow key iterates through all previous lines of input. My application does not contain any code for this feature. What part of Windows provides this? How can I disable it?

I can only image that it's either a feature of the console subsystem or implemented in Console.ReadLine().

Here is some sample code that exhibits the described behavior:

namespace ConsoleApplication
{
    class Program
    {
        static void Main(string[] args)
        {
            string input;
            do
            {
                input = System.Console.ReadLine();
            } while (input != "exit");
        }
    }
}

I would like to disable the history feature for now, and re-implement it later using my own code. The current behavior is too limited.

TheFogger
  • 2,399
  • 1
  • 20
  • 22
  • The only thing I found is this - http://www.clearallhistory.com/clear-run-history.html . Its not an ideal solution, but you could clear out the history perhaps before you ask for input. The side effect is that it clears the history for any command prompt that you open on the machine. – arunkumar Aug 07 '11 at 14:08
  • I was also surprised by this as it happened to me, but I was totally pleased with this. "awesome", I thought. But now I want to intercept Tab to do completion and it seems i may lose that feature if I need to get the keys one by one by hand. Cool feature but not extensible it seems. Also why not go all the way and implement Ctrl-R history lookup ? MS.... – v.oddou Jul 02 '15 at 02:34
  • ACTUALLY, I just discovered by accident that the console supports F8 (bash Ctrl+r) and F9 (bash !n) ! this is absolute awesomeness all of a sudden, kudos MS. http://ss64.com/nt/syntax-keyboard.html – v.oddou Jul 02 '15 at 07:34

4 Answers4

20

you can change this behaviour of windows programmatically by calling SetConsoleHistoryInfo with a correctly setup CONSOLE_HISTORY_INFO structure... there seems to be no managed class/method so you will have to use DllImport etc.

http://msdn.microsoft.com/en-us/library/ms686031%28v=VS.85%29.aspx
http://msdn.microsoft.com/en-us/library/ms682077%28v=VS.85%29.aspx

IF need be - several other aspects of the console can be handled in a managed way - see c# console, Console.Clear problem

Community
  • 1
  • 1
Yahia
  • 69,653
  • 9
  • 115
  • 144
  • +1 I must somehow have missed that API function. I had that page open already :-) I think I am not going to bother with trying to disable the feature after all. I will rather use my own input processing using ReadKey(). This should completely sidestep the history. – TheFogger Aug 07 '11 at 14:43
4

The history feature is built into the Windows Command shell, it is not a feature of your application. AFAIK there's no way to disable this in your code as it's specific to the Windows Shell Environment (unless there's a setting that can be changed, which there probably is)

You could possibly override the default behavior by using a key listener to get all up arrow keypresses and execute your own code, that way the event doesn't drop down to the shell to handle.

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
  • Well the thing is that your answer doesn't really give him a way of doing what he really wants as he wants to control things programatically from my understanding. That is just a workaround for his setup. Ideally he wants his OWN implementation of command history as he says he would like to re implement it with his own code. – Jesus Ramos Aug 07 '11 at 14:14
  • Lovin the downvote and the 3 answers that are almost exactly the same. Good job guys – Jesus Ramos Aug 07 '11 at 14:18
  • I didn't downvote anyone. I usually reserve downvotes for answers that are WAYYYYY off. – Jesus Ramos Aug 07 '11 at 14:19
  • It's ok they're just "retweeting" answers. A challenger has appeared with the same answer again.... – Jesus Ramos Aug 07 '11 at 14:20
  • "Well the thing is that your answer doesn't really give him a way of doing what he really wants as he wants to control things programatically from my understanding." Does this answer do that? – David Heffernan Aug 07 '11 at 14:31
  • This also works when you start the console mode app from VS or Explorer. No Windows Command shell is running. Your answer is wayyyy off I'm afraid. – Hans Passant Aug 07 '11 at 14:32
  • Hans, well that still runs the windows shell. @David, I tell him that it's possible to handle the up arrow keypress event so that he can use his own implementation rather than the up arrow event being handled by the shell. – Jesus Ramos Aug 07 '11 at 14:35
  • I think the term "Windows Command Shell" is incorrect. Also, "Windows Shell" usually refers to something other that console windows. However, when one interprets both terms as just [Console](http://msdn.microsoft.com/en-us/library/ms682010(v=VS.85).aspx) then the answer is correct :-) – TheFogger Aug 07 '11 at 14:39
  • @TheFogger, see the thing is that the environment running on that console is the windows shell. It is the underlying structure that handles any I/O the console receives. I tried to be explicit by saying anything that makes use of this shell will usually exhibit the same behavior be it VS console or Explorer console. – Jesus Ramos Aug 07 '11 at 14:41
  • @Jesus This is the [Windows Shell](http://en.wikipedia.org/wiki/Windows_shell), aka GUI. I think this is just a misunderstanding of terms. In my understanding, there are "Consoles" which display to "Console Windows". Consoles manage the IO for "Console Applications". Then there is cmd.exe, the equivalent of a "unix shell" like bash or zsh. cmd.exe is a console application, just like my application. – TheFogger Aug 07 '11 at 14:53
  • @TheFogger, the shell is the underlying handler. The console is just a handler for I/O or the GUI frontend – Jesus Ramos Aug 07 '11 at 14:59
4

Yes, this is a feature of the console subsystem, not your application. To change it, click the console's control box (top left), properties, options tab: "Command history." The default is 50 items, 4 buffers. Supposedly this can be configured programmatically with DOSKEY from the command line, but a few minutes tinkering didn't lead me anywhere.

ALT+F7 will clear the command history, as will executing the command DOSKEY /reinstall. I tested in Windows 7.

Update: The corresponding Win32 API call is SetConsoleHistoryInfo and the p/invoke signature can be found at http://pinvoke.net/default.aspx/kernel32/SetConsoleHistoryInfo.html

x0n
  • 51,312
  • 7
  • 89
  • 111
  • Those pinvokes in that link are wrong. It's uints, not ushorts and also you need to pass a pointer as reference. – Matthias Nov 15 '20 at 21:46
0

Not tested, but it looks like passing an instance of CONSOLE_HISTORY_INFO to SetConsoleHistoryInfo with buffer size and count set to 1 would give the same control as the console window properties dialogue.

P/Invoke definitions at pinvoke.net

Also note this requires Windows V6 or later (ie. Vista/2008/7/2008R2).

Richard
  • 106,783
  • 21
  • 203
  • 265