如何让SET命令不等待回答?

时间:2014-06-05 16:03:40

标签: batch-file batch-updates

我已经制作了一个聊天程序并且效果很好,我唯一的问题是SET / P命令会等到你按某个东西然后按ENTER键。我的代码出现了问题:

: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

我想一直更新TYPE命令,但你需要输入一些东西。无论如何我可以解决这个问题吗? 编辑:我真的不想要另一个cmd屏幕

1 个答案:

答案 0 :(得分:2)

假设您确实已经实时更新了文本。当用户开始输入文本,然后另一个用户发送要同时显示的文本时会发生什么。你只有一个窗口 - 所以你得到一个乱七八糟的混乱(假设你可以弄清楚如何在技术上实现它。)

离功能性聊天程序还有很长的路要走 - 你还没有完全考虑过问题。

1)您需要两个独立更新的窗口:

  • 用户可以输入文字的输入窗口

  • 一个对话窗口,实时显示所有参与者的运行对话框。

Windows批处理不支持多个窗口。但您可以通过为每个用户运行两个批处理进程来模拟它,一个用于输入,另一个用于对话框输出。单个批处理脚本可用于两个进程。父脚本可以使用START命令启动多个批处理进程。每个批处理过程都会有自己的控制台窗口。

2)一次只能有一个人(进程)写入文本文件。如果两个人同时尝试写作,您认为会发生什么?一个会成功,另一个会失败。您需要一种方法来检测故障并自动重试直到成功。我描述了一种在How do you have shared log files under Windows?实现此目的的简单方法。

3)如果用户按下<Enter>而没有输入任何内容,SET / P将只返回上一个条目。您应该在SET / P语句之前清除文本变量。 编辑 - 我现在看到OP在我没想到的地方已经有了这个

4)每次有更新时,您都不想从头开始重新键入整个对话框。您只想显示新添加的行。可以将输入重定向到无限的FOR / L循环,并且在循环内可以使用SET / P来读取最近的行。如果没有附加任何内容,则它将不返回任何内容(假设变量在SET / P之前被清除)。如果没有收到任何内容,你根本就不会做任何事情。

这是一个非常粗略的工作示例,演示了上述概念。没有办法退出该程序。您必须关闭两个控制台窗口才能退出。

@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

在这是一个真正有用的聊天程序之前还有很长的路要走。但这是一个很好的起点。还可以添加一些其他内容。

5)为每个独立聊天启动新对话文件的方法。

6)邀请一个或多个用户加入聊天的方法。

7)退出程序的干净方法,包括关闭附加控制台窗口。这需要进程间通信。我在http://www.dostips.com/forum/viewtopic.php?t=4741的SNAKE.BAT游戏中演示了这一点。警告 - 该脚本中有许多高级概念,因此提取相关信息可能是一个挑战; - )

8)让对话窗口具有可滚动的显示缓冲区会很好。用户可以通过控制台属性控制缓冲区的大小,但以编程方式控制它会很不错。本机批处理不能这样做,但我展示了混合PowerShell /批处理如何在CMD: Set buffer height independently of window height

执行此操作