1

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.

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. 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?

@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"
Henk Holterman
  • 236,989
  • 28
  • 287
  • 464
Klicker
  • 1,112
  • 1
  • 15
  • 33
  • Be explicit: are you able to fix the C# application? What equivalent exactly? – Henk Holterman Aug 08 '16 at 21:12
  • @HenkHolterman, I have no access to the code within the C# application, so its not something I can change (despite wanting to). Additionally, I know very little of C# in general. I'm really looking for a way around this via by batch file, if one exists. Thanks – Klicker Aug 08 '16 at 21:17

4 Answers4

1

Try this (note the collated dot after 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:

echo.| pause

echo. is not echo. It just prints a newline, just what you need to trigger the pause.

Jean-François Fabre
  • 126,787
  • 22
  • 103
  • 165
  • no luck with this - throws unhandled exception. Unhandled Exception: System.InvalidOperationException: Cannot read keys when either application does not have a console or when console input has been redirected from a file. Try Console.Read. at System.Console.ReadKey(Boolean intercept) at CoT.Program.Main(String[] args) – Klicker Aug 08 '16 at 21:33
  • ouch, the program detects if stdin is really interactive. With this it detects the redirection and crashes... I guess you'll have to change the C# code. – Jean-François Fabre Aug 08 '16 at 21:37
  • no worries, not worth going into this at the moment. Thanks for your help anyway. – Klicker Aug 08 '16 at 21:39
  • I'm sure there's a way to create a batch exception (avoiding the requester): in that case, when you get the exception, you have completed your processing. Not a problem if the program crashes there! – Jean-François Fabre Aug 08 '16 at 21:46
  • that question is an anti-duplicate of this one : http://stackoverflow.com/questions/11512821/how-to-stop-c-sharp-console-applications-from-closing-automatically. Should the other the proposed method been chosen for your program, my trick would have worked sigh :) – Jean-François Fabre Aug 08 '16 at 21:51
  • Actually you are echoing _space_ + _line-break_, unless you remove the _space_ before the pipe `|`... – aschipfl Aug 08 '16 at 23:21
  • Yeah, gets me everytime, edited out. Still does not solve it. – Jean-François Fabre Aug 09 '16 at 00:56
0

Not sure whether will it work if your console app already have a Console.ReadLine() or Console.ReadKey() method but instead of just calling the *.exe use the Start command which will run the executable in a separate window like

start "MyConsoleTask" C:\Applications\Job\Job.exe > C:\Applications\Job\Job_Output\"Output_%date:/=-% %time::=-%.txt"
Rahul
  • 71,392
  • 13
  • 57
  • 105
  • Thanks for the suggestion Rahul, however the problem here is that using the start command sends the console app output to the CMD window, instead of sending it to the output file. It also doesn't display the message 'The application is running...'. I really need the output to be sent to a file for logging purposes. Any other ideas? Thanks again – Klicker Aug 08 '16 at 21:00
  • 1
    @Klicker, do you really have `Console.ReadLine()` or `ReadKey()` in your console app? – Rahul Aug 08 '16 at 21:07
  • Sorry @Rahul, I have no idea, I didn't write the app and know very little of C#. When I run the application directly via the .exe, when it comes to the end of the process it displays the old 'Press any key to continue... message', which is what causes the CMD window to remain open. I'm looking for a way to make my batch file press the key for me, or something similar. Thanks again – Klicker Aug 08 '16 at 21:14
  • @Klicker, not sure how much of help it would be but take a look at this post http://stackoverflow.com/questions/17038282/press-keyboard-keys-using-a-batch-file – Rahul Aug 08 '16 at 21:25
  • cheers for this. Had a look at this one before raising this question as I thought there must be a more simple solution. I'll maybe tackle this at some point, but its not worth it right now. Thanks for your suggestions none-the-less. – Klicker Aug 08 '16 at 21:35
0

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.

: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.

NOTE: the call and/or goto trick is discussed here

elzooilogico
  • 1,623
  • 2
  • 13
  • 16
0

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:

Leonardo Pina
  • 460
  • 1
  • 7
  • 17