Waiting for keypress in a console - I've got problems.

6 views
Skip to first unread message

R.Wieser

unread,
Dec 28, 2020, 8:50:25 AM12/28/20
to
Hello all,

I run scripts in a console window, and sometimes need to have them wait for
a keypress before continuing. For that I found the below code :

- - - - - - - - - - - - - - - - - - - -
Wscript.StdOut.Write vbNewLine & "Press ENTER to continue. "

Do While Not WScript.StdIn.AtEndOfLine
Input = WScript.StdIn.Read(1)
Loop
- - - - - - - - - - - - - - - - - - - -

This works well the first time, but for some reason the following times it
responds as if the Enter key was already pressed.

I've been looking forr a way to flush the StdIn buffer, but could not find
anything.

At some point I changed the code to the below :

- - - - - - - - - - - - - - - - - - - -
Do While WScript.StdIn.Read(1) <> vbCR
loop
- - - - - - - - - - - - - - - - - - - -

While that works well, the problem with that is that it likely won't work
too well with any kind of redirected input (where the (last) line does not
necessarily end with a CR(LF) ...

So, my simple question (yeah, right :-) ) is : does anyone know about a way
to either only wait for just the keyboard (ignoring redirection) or flush
the input buffer before waiting for the Enter key to be pressed.

And now I think of it, I have no idea why the first bit of code waits to
begin with. Somehow not having pressed any keys yet does not register as an
AtEndOfLine state ?

Regards,
Rudy Wieser



Evertjan.

unread,
Dec 28, 2020, 11:17:00 AM12/28/20
to
"R.Wieser" <add...@not.available> wrote on 28 Dec 2020 in
microsoft.public.scripting.vbscript:

> Hello all,
>
> I run scripts in a console window, and sometimes need to have them wait
> for a keypress before continuing. For that I found the below code :
>
> - - - - - - - - - - - - - - - - - - - -
> Wscript.StdOut.Write vbNewLine & "Press ENTER to continue. "
>
> Do While Not WScript.StdIn.AtEndOfLine
> Input = WScript.StdIn.Read(1)
> Loop
> - - - - - - - - - - - - - - - - - - - -

If you are content with 'enter':

===================
WScript.Echo "Press [ENTER] to continue..."
' This will not return until [ENTER] is pressed.
WScript.StdIn.ReadLine
WScript.Echo "Done."
===================

Or with a box:

===================
MsgBox("Press [ENTER] to continue...")
WScript.Echo "Done."
===================

--
Evertjan.
The Netherlands.
(Please change the x'es to dots in my emailaddress)

R.Wieser

unread,
Dec 28, 2020, 12:18:13 PM12/28/20
to
Evertjan,

> If you are content with 'enter':
...
> WScript.StdIn.ReadLine

Yeah, thats a lot simpler (why did I not think of that myself ?). Thanks.

> Or with a box:

That's what I'm trying to replace. :-) (I'm often running the scripts in a
full-screen console)

By the way, do you have any idea why that first code sample I posted waits
until 'Enter' is pressed ? Somehow I read it as something that should
just empty the StdIn buffer.

Regards,
Rudy Wieser




"Evertjan." <exxjxw.h...@inter.nl.net> wrote in message
news:XnsACA1AFC...@194.109.6.166...

Evertjan.

unread,
Dec 28, 2020, 6:21:18 PM12/28/20
to
Methinks the budder is only filled with a complete line,
not with a character.

JJ

unread,
Dec 28, 2020, 11:44:50 PM12/28/20
to
On Mon, 28 Dec 2020 14:50:17 +0100, R.Wieser wrote:
> Hello all,
>
> I run scripts in a console window, and sometimes need to have them wait for
> a keypress before continuing. For that I found the below code :
>
> - - - - - - - - - - - - - - - - - - - -
> Wscript.StdOut.Write vbNewLine & "Press ENTER to continue. "
>
> Do While Not WScript.StdIn.AtEndOfLine
> Input = WScript.StdIn.Read(1)
> Loop
> - - - - - - - - - - - - - - - - - - - -
>
> This works well the first time, but for some reason the following times it
> responds as if the Enter key was already pressed.

That usually caused by input buffer overrun.

> I've been looking forr a way to flush the StdIn buffer, but could not find
> anything.

The only workaround I could think of is to use the CHOICE tool to indirectly
flush the input buffer.

> At some point I changed the code to the below :
>
> - - - - - - - - - - - - - - - - - - - -
> Do While WScript.StdIn.Read(1) <> vbCR
> loop
> - - - - - - - - - - - - - - - - - - - -
>
> While that works well, the problem with that is that it likely won't work
> too well with any kind of redirected input (where the (last) line does not
> necessarily end with a CR(LF) ...

Reading the input buffer one character at a time is too slow. It'll likely
to cause input buffer overrun when the total possible (continuous) data size
is larger than the size of the input buffer. Even reading one line at a time
can be too slow depending on the speed of the input.

R.Wieser

unread,
Dec 29, 2020, 2:28:54 AM12/29/20
to
Evertjan,

> Methinks the budder is only filled with a complete
> line, not with a character.

That part I understand.

But if nothing has been put into the buffer yet, why than does that "Do
While Not WScript.StdIn.AtEndOfLine" loop (and thus wait) ?

The only thing I can think of is that the AtEndOfLine checks, in case of the
keyboard, for a CR. Yet, adding another "WScript.StdIn.Read(1)" below the
loop to get rid of that EOL char doesn't help.

Regards,
Rudy Wieser


R.Wieser

unread,
Dec 29, 2020, 2:28:54 AM12/29/20
to
JJ,

> That usually caused by input buffer overrun.

In my case that would be rather hard, as I start the (test) script by
double-clicking it. Also, all chars you type (upto the 'Enter') are
displayed - and nothing shows.

> The only workaround I could think of is to use the
> CHOICE tool to indirectly flush the input buffer.

I've never been able to start another console-based program into the context
of the script currently running. They always get their own console window.
Which includes their own, seperate input buffers ...

Please advise if I overlooked something though.

> Reading the input buffer one character at a time is too slow.

Being slow is not really a problem, as I'm normally waiting for the user to
press a/the key. I just want to make sure that it doesn't lock up when I,
for whatever reason, redirect StdIn from a file or similar.

Regards,
Rudy Wieser


Evertjan.

unread,
Dec 29, 2020, 7:26:20 AM12/29/20
to
"R.Wieser" <add...@not.available> wrote on 29 Dec 2020 in
microsoft.public.scripting.vbscript:
Methinks the .Read(1) is ment to provide for piped files,
not for the keyboard. '

So if you type "abcd" + cr,
the .Read(1) will reas the "a" when the cr is entered.
[not tested]

Would there be a timeout perhaps?

R.Wieser

unread,
Dec 29, 2020, 8:46:22 AM12/29/20
to
Evertjan,

> So if you type "abcd" + cr,
> the .Read(1) will reas the "a" when the cr is entered.

It does. However, outputting all read characters inside that loop displays
all that have been typed. Which means that the buffer should be empty when
the loop exits

I did some more checking and it turns out that when the loop ends there are
/two/ characters still in the buffer. Yup, a CR,LF pair - with seemingly
both being recognised as AtEndOfLine characters. So just reading one last
character was not enough to solve the problem, I needed to read two.

But if I do that .... I will definitily get into troube when I redirect a
file which uses single-character EOLs. IOW, not a good solution.

> Would there be a timeout perhaps?

I wish ! That would allow me to do something else too : looping thru some
code as long as a specific key has not been pressed.

Althoug the former is solved by using .ReadLine, there is no way to get the
latter effect (a "no wait" check for a keypress).

Oh well, I can always see if I can slap something together myself. :-)

Thanks for the help.

Regards,
Rudy Wieser


Reply all
Reply to author
Forward
0 new messages