对于凌乱的标题感到抱歉。
我想有效地从另一个批处理文件/窗口获取输入(例如:批处理文件中的选择命令)并将其发送到另一个批处理文件。基本上它会在另一个窗口中“键入”它。现在,我不能让第一个批处理文件打开一个新文件,因为如果我这样做,我只会打开另一个java实例
第一批文件的代码:
:menu
cls
echo.
echo Please select option using keys 1 or 2:
echo. [1] Start server
echo. [2] Stop server
echo. [3] Say "hi"!
choice /C 12 /N
if %errorlevel%==1 goto start-server
if %errorlevel%==2 goto stop-server
if %errorlevel%==3 goto test-command
goto menu
:start-server
echo Starting server...
start start.bat
pause
goto menu
:stop-server
echo Stopping server
echo stop > task start.bat
pause
goto menu
:test-command
echo say hi > task start.bat
pause
goto menu
第二批文件的代码:
@echo off
java -Xms1024M -Xmx2048M -jar spigot_server.jar
pause
像echo stop > task start.bat
有没有人对如何实现这一点有任何想法?我愿意为第一个文件使用除批处理之外的任何东西(因为第二个文件要求它是一个批处理脚本),但我不想下载任何东西。
答案 0 :(得分:1)
我假设你的java服务器是一个接受重定向stdin输入的控制台进程。我还假设如果从文件读取并且它到达输入文件的末尾,您的服务器进程将终止。我还假设你不想修改你的java代码。
您无法使用管道在两个窗口之间进行通信。但是你可以使用一个文件。
您的主批处理脚本可以将命令写入服务器读取的输入文件。但是服务器无法直接读取命令。需要使用发件人批处理脚本将命令中继到服务器。
主脚本通过启动发送脚本启动服务器,输入重定向到输入文件,发送脚本输出通过管道传送到服务器进程。
发送脚本是一个循环,它重复使用FOR / F通过FINDSTR读取输入文件。 FINDSTR读取stdin(已经重定向到输入文件)。这样做的原因是因为FINDSTR每次调用时都不会重置文件指针。如果没有新命令,则它不返回任何内容。但是如果在输入文件中添加了一行,那么FINDSTR会将其拾起。
添加到输入文件的每个命令都包含两个由冒号分隔的部分。
我选择将主脚本和发件人脚本合并到一个脚本中。该脚本通过使用:send参数调用自身来启动发送方。如果第一个参数是:send,则它将分支到发送者代码。
我没有你的java服务器代码。因此,出于演示目的,我使用了cmd.exe作为我的"服务器"。显然,我的:菜单中的命令适用于cmd.exe。您可以替换您的java程序并适当地更改命令。
请注意,服务器窗口在启动时会自动窃取焦点。您必须单击父窗口才能重新获得焦点,以便输入命令。
@echo off
if "%~1" equ ":send" goto :send
setlocal
set "inputFile=input.txt"
set "serverCommand=cmd.exe"
:initMenu
echo(
echo Press one of the option keys
echo [S] Start server
echo [Q] Quit
choice /c SQ /n
if errorlevel 2 exit /b
echo Starting server...
echo(
echo You must click on this main window to regain focus.
copy nul "%inputFile%" >nul
start "" cmd /c ""%~f0" :send <"%inputFile%" | cmd"
call :menu
echo Server stopped
goto :initMenu
:menu
echo Press one of the option keys
echo [D] Date
echo [T] Time
echo [P] Ping
echo [S] Stop server
choice /c DTPS /N
>>"%inputFile%" (
if errorlevel 4 (
echo exit:exit
exit /b
) else if errorlevel 3 (
echo go:ping /n 5 localhost
) else if errorlevel 2 (
echo go:time /t
) else (
echo go:date /t
)
)
echo(
goto :menu
:send
for /f "delims=: tokens=1*" %%A in ('findstr "^"') do (
echo(%%B
if /i %%A equ exit %%A
)
goto :send
请注意:send例程不断轮询stdin,因此它会将处理器(或处理器核心)挂起接近100%。你可以在循环中添加一个PING延迟,这样它就不会占用CPU资源,但服务器也不会那么响应。
如果您的服务器进程在到达重定向输入结束时没有自动终止,那么您不需要发件人批处理。您只需使用
在主脚本中启动服务器即可start cmd /c ""yourServerCommand <"%inputFile%""
或者如果它当前在到达文件末尾时终止,但您愿意修改服务器代码,那么您仍然可以执行上述操作。你可以修改你的java代码来连续轮询输入,只读取一行,如果不是在文件的末尾。该进程只有在收到某种类型的退出命令时才会终止。
如果您的服务器不是控制台进程,那么您需要AutoIt之类的命令来向服务器窗口发送命令。或者您可以使用VBScript或JScript以及SendKeys method。
推出自己的解决方案即使您的服务器进程是控制台进程,您仍然可能希望使用AutoIt或SendKeys,因为它更直接。
答案 1 :(得分:-2)
这是一种使用参数的方法,正如@Dennis van Gils建议的那样。
<强> FIRST.BAT 强>
@echo off
:menu
cls
echo.
echo Please select option using keys 1 or 2:
echo. [1] Start server
echo. [2] Stop server
echo. [3] Say "hi"!
choice /C 123 /N
if %errorlevel%==1 goto start-server
if %errorlevel%==2 goto stop-server
if %errorlevel%==3 goto test-command
goto menu
:start-server
second.bat start
goto menu
:stop-server
second.bat stop
goto menu
:test-command
second.bat hi
goto menu
<强> SECOND.BAT 强>
@echo off
if "%1"=="start" (
echo Starting Server...
rem java -Xms1024M -Xmx2048M -jar spigot_server.jar
)
if "%1"=="stop" (
echo Stopping Server...
)
if "%1"=="hi" (
echo Hi there!
)