How to make the SET command not wait for answer?

可紊 提交于 2019-12-12 02:46:07

问题


I've made a chat program and it works great, the only problem I have is that the SET /P command will wait until you press something and then press ENTER. There's my code that I got problems with:

:CHAT
CLS
SET TEXT=
TYPE "%FILESDIR%\Files\CHAT.cht" << I need this line active all the time.
ECHO.
SET /P TEXT=Text: 
IF NOT "%TEXT%"=="" ECHO %USERNAME%: %TEXT% >> "%FILESDIR%\Files\CHAT.cht"
PING LOCALHOST -n 1 > nul
GOTO CHAT

I want to update the TYPE command all the time, but you need to type something. Is there anyway I can get around this? EDIT: I really don't want another cmd screen


回答1:


Suppose you did have the text updated continuously, in real time. What happens when the user begins to enter text, and then the other user sends text to be displayed at the same time. You only have one window - so you get a jumbled mess (assuming you could figure out how to make it happen technically).

You are a long way from having a functional chat program - you haven't completely thought out the issues.

1) You need two windows that are updated independently:

  • An input window where the user can enter text

  • A dialog window that displays the running dialog of all participants, in real time.

Windows batch doesn't support multiple windows. But you can emulate it by having two batch processes running for each user, one for input, the other for dialog output. A single batch script can be used for both processes. The parent script can launch multiple batch processes using the START command. Each batch process will get its own console window.

2) Only one person (process) can write to the text file at a time. What do you think happens if two people try to write at the same time? One will succeed, and the other will fail. You need a method to detect failure and automatically try again until success. I describe a simple method to achieve this at How do you have shared log files under Windows?.

3) SET /P will simply return the previous entry if the user presses <Enter> without typing anything. You should clear the text variable prior to your SET /P statement. EDIT - I now see the OP already had this in a place I did not expect

4) You don't want to retype the entire dialog from the beginning every time there is an update. You only want to dispaly the newly appended lines. It is possible to redirect input to an endless FOR /L loop, and within the loop you can use SET /P to read the most recent line. If nothing has been appended, then it will return nothing (assuming the variable was cleared before SET /P). You simply don't ECHO anything if nothing was received.

Here is a very crude working example that demonstrates the above concepts. There is no way to exit the program. You will have to close both console windows to quit.

@echo off
setlocal enableDelayedExpansion
set "dialog=dialog.txt"
if "%~1" equ ":input" (
  title Chat Input
  goto :input
)
start "" "%~f0" :input
title Chat Dialog

::Show Dialog
<"%dialog%" (  for /l %%N in () do (
  set "text="
  set /p "text="
  if defined text echo(!text!
))


:input
cls
set "text="
set /p "text=>"
:write
2>nul (
  >>"%dialog%" (
    echo(%username%: !text!
    (call )
  ) || goto :write
)
goto :input

There is still a long way to go before this is a truly useful chat program. But it is a good starting point. Some additional things that could still be added.

5) A way to start a new dialog file for each independent chat.

6) A way to invite one or more users to join the chat.

7) A clean way to exit the program, including closing of the additional console window. This requires interprocess communication. I demonstrate this in my SNAKE.BAT game at http://www.dostips.com/forum/viewtopic.php?t=4741. Warning - there are a lot of advanced concepts in that script, so extracting the relevent information might be a challeng ;-)

8) It would be nice to have the dialog window have a scrollable display buffer. The user can control the size of the buffer via the console properties, but it would be nice to control it programmatically. Native batch cannot do this, but I show how hybrid PowerShell/batch can do this at CMD: Set buffer height independently of window height



来源:https://stackoverflow.com/questions/24064970/how-to-make-the-set-command-not-wait-for-answer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!