This is a minimal example that illustrates my problem:
:: test.bat
@echo off
call test2.bat 2>&1 | findstr foo
echo done calling test2
:: test2.bat
@
I believe I can illustrate the problem without any batch file at all. The following pipe construct does not complete until after notepad.exe is closed:
start notepad | findstr "^"
I would expect that notepad would be executing in a new process that is totally disassociated from the cmd.exe pipe, and the only thing being piped would be the output of the START command itself (which is none). The START command returns "instantly", yet the pipe remains open for as long as notepad is running.
I don't know if it is an inherited I/O stream that is keeping the pipe open, but I can prove that the notepad process is inheriting streams in a way that might be the root of the problem. This is basically the same issue that was brought up at Issue with output redirection in batch.
Here is a simple batch script: test.bat
@echo off
call :test >nul
echo done calling test.bat
exit /b
:test
start notepad
Notice that stdout has been redirected to NUL when notepad is STARTed, due to the redirection of call :test >nul
.
Now look at what happens when I issue a series of commands from the command line, starting off with test.bat having stdout redirected to a file:
C:\test>test.bat >test.txt
C:\test>REM The command returns immediately, and notepad remains open
C:\test>type test.txt
done calling test.bat
C:\test>echo This fails as long as notepad remains open >test.txt
The process cannot access the file because it is being used by another process.
C:\test>type test.txt
done calling test.bat
C:\test>REM Now I close notepad
C:\test>echo This works once notepad is closed >test.txt
C:\test>type test.txt
This works once notepad is closed
C:\test>
I am still blown away by this behavior. It seems totally illogical.
I don't think there is any way to prevent the stream inheritance with cmd.exe.
Perhaps Harry Johnston's suggestion could solve the issue (from the question comments): "I'd write a very simple executable to call CreateProcess with inheritance disabled."