简体   繁体   English

批处理文件调用控制台应用程序 - 使 CMD 窗口保持打开状态

[英]Batch File calling Console Application - Leaves CMD window open

I am calling a C# Console Application via batch file, in order to send the application output into a text file, with the date/time etc.我正在通过批处理文件调用 C# 控制台应用程序,以便将应用程序输出发送到带有日期/时间等的文本文件中。

The problem I have is that when the console application completes, it leaves the batch window open, because there is a PAUSE (the C# equivalent), so a key must be pressed for the window to close.我遇到的问题是,当控制台应用程序完成时,它使批处理窗口保持打开状态,因为有一个 PAUSE(C# 等效项),因此必须按下一个键才能关闭窗口。 This means I do not know when the job has finished.这意味着我不知道工作何时完成。

Is there a way I can make the CMD window close when the application finished, without having to change the C# Application code?有没有办法在应用程序完成时关闭 CMD 窗口,而不必更改 C# 应用程序代码?

@ECHO================================================================================
@ECHO The Application is currently running and may take some time. Please wait...
@ECHO================================================================================
@ECHO OFF

C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"

Try this (note the collated dot after echo ):试试这个(注意echo之后的整理点):

echo.| C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"

I have tried with pause and it works well:我试过pause ,效果很好:

echo.| pause

echo. is not echo .不是echo It just prints a newline, just what you need to trigger the pause.它只是打印一个换行符,这正是触发暂停所需的内容。

如果您的控制台应用程序已经有Console.ReadLine()Console.ReadKey()方法,则不确定它是否可以工作,但不是仅调用*.exe而是使用Start命令,该命令将在单独的窗口中运行可执行文件,例如

start "MyConsoleTask" C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"

If you have not access to the console app source code, you may try a workaround如果您无法访问控制台应用程序源代码,您可以尝试一种解决方法

@echo off
@echo================================================================================
@echo The Application is currently running and may take some time. Please wait...
@echo================================================================================

set "timeStamp=%date:/=-%_%time::=-%
set "timeStamp=%timeStamp:~0,-3%"      & rem remove ,centiseconds.

set "logFile=C:\Applications\Job\Job_Output\Output_%timeStamp%.txt"

rem start the exe in the same cmd window
start /B "" """C:\Applications\Job\Job.exe" > "%logFile%"""

rem wait for process startup
ping 1.1.1.1 -n 1 -w 750 >NUL

rem wait for logFile to be closed. This may flag that job.exe has ended
:wait
ping 1.1.1.1 -n 1 -w 50 >NUL & rem this avoids processor load
2>nul (>>"%logFile%" call )||goto :wait

rem send a key to the console. This may be captured by the exe file
set "_vbs_file_=%TEMP%\sendConsole.vbs"
(
  echo/ set oWS ^= CreateObject^("wScript.Shell"^)
  echo/ wScript.Sleep 50
  echo/ oWS.SendKeys "{ENTER}"
)>"%_vbs_file_%"
if exist "%TEMP%\sendConsole.vbs" (set "_spawn_=%TEMP%\sendConsole.vbs") else (set "_spawn_=sendConsole.vbs")
ping 1.1.1.1 -n 1 -w 50 >NUL
start /B /WAIT cmd /C "cls & "%_spawn_%" & del /F /Q "%_spawn_%" 2>NUL"

@echo================================================================================
@echo Process completed. I guess...
@echo================================================================================

exit/B

so,所以,

start /B ...

starts the job.exe executable in the same cmd window.在同一个 cmd 窗口中启动job.exe 可执行文件

:wait
ping 1.1.1.1 -n 1 -w 50 >NUL & rem this avoids processor load
2>nul (>>"%logFile%" call )||goto :wait

waits until logfile is closed, so it may indicate that the previous proccess has ended.等待直到日志文件关闭,所以它可能表明前一个过程已经结束。

set "_vbs_file_=%TEMP%\sendConsole.vbs"
(
  echo/ set oWS ^= CreateObject^("wScript.Shell"^)
  echo/ wScript.Sleep 50
  echo/ oWS.SendKeys "{ENTER}"
)>"%_vbs_file_%"
if exist "%TEMP%\sendConsole.vbs" (set "_spawn_=%TEMP%\sendConsole.vbs") else (set "_spawn_=sendConsole.vbs")
ping 1.1.1.1 -n 1 -w 50 >NUL
start /B /WAIT cmd /C "cls & "%_spawn_%" & del /F /Q "%_spawn_%" 2>NUL"

send the enter key to the console, so the process waiting a keystroke may capture it.将回车键发送到控制台,因此等待击键的进程可能会捕获它。

NOTE: the ping wait trick works fine only if the IP is unreachable.注意:只有当 IP 无法访问时, ping 等待技巧才能正常工作。

NOTE: the call and/or goto trick is discussed here注意:这里讨论了调用和/或转到技巧

we gotta simulate a key press here, therefore we should toy with the keyboard buffer.我们必须在这里模拟按键,因此我们应该玩弄键盘缓冲区。

I am no Batch expert and this is the answer I found searching how to press keys with a batch:我不是批处理专家,这是我在搜索如何使用批处理按键时找到的答案:

@if (@CodeSection == @Batch) @then
@echo off
set SendKeys=CScript //nologo //E:JScript "%~F0"
rem Open the command here
start "" /B Job.exe > JobOutput.txt
rem sends the keys composing the string "I PRESSED " and the enter key
%SendKeys% "I PRESSED {ENTER}"
goto :EOF

@end

// JScript section
WScript.CreateObject("WScript.Shell").SendKeys(WScript.Arguments(0));

source:来源:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM