3

In a Windows environment, are executable programs that are used to process piped output guaranteed to be unique tasks if called from different CMD environments?

For example, suppose script1.cmd contains this line:

echo "some logging information" | my_pipe_program >> logfile1.txt

Also there is script2.cmd that contains this line:

echo "some other information" | my_pipe_program >> logfile2.txt

If script1 and script2 happen to run at the same time, is Windows going to call separate instances of my_pipe_program.exe?

I'm getting sporadic errors where a command script fails with the error "The process cannot access the file because it is being used by another process" This error always occurs right after a line that pipes through my_pipe_program.exe.
It causes the CMD script to stop right at that spot, leaving the CMD window open.

The conflict could be with my_pipe_program.exe or it could be logfile2.txt. The program my_pipe_program.exe is used in multiple CMD files, which could potentially run at the same time. The logfile is unique to the CMD file, so it seems less likely to be the culprit, unless Windows is failing to close it after the CMD file exists. Is there any approach to diagnose the problem and fix the error?

Related question - is there any way to trap and handle the "...being used by another process" error and prevent the CMD file from aborting?

tim11g
  • 425
  • 5
  • 9
  • 21

1 Answers1

1

It sounds like the issue may be with that EXE and how it handles being called on the same machine running concurrently in memory perhaps. Enabling advanced logging at this level to capture verbose detail or stack traces while emulating concurrent runs in memory from the same machine just like when the issue occurs may be best for the most accurate answer WHY it's doing this.

See my answer here (SuperUser) on SuperUser from the other day how to kill a process with batch if the CMD or BAT file is LIKE a certain name.

You could incorporate something like this to check and see if maybe something has been running for over a certain period of time with those batch file names and kill but you'd have to look at other options in WMIC to see if there's a timer, etc. if that'd work in your case. Fixing the EXE logic at that level and catching the error and ending may be best though if you control at that level.


ADDITIONAL IDEAS

A simple solution may be to create a lock file when the batch CMD file kicks off so all scripts that launch that same EXE from the same machine first check to see if the lock file exists, if it does, then end the script (or perhaps pause for so many minutes and then check again, etc.).

You could just end the script [GOTO locked] or pause it for so many seconds, then go to that routine [GOTO lockedrecheck] and check again if the other process is done and deleted the file if that'd suffice in your case.

If the lock file doesn't exist, it'd create the file, then run the process and when it's done, delete the lock file so other processes can run (example below).

You can also add the 2<&1 to the end of your log file to get more detail if the EXE allows for it to be captured that way where it wouldn't otherwise (example script logic below).

LOCK FILE EXAMPLE (end it or pause it and recheck)

<ABOVE LOGIC>
<ABOVE LOGIC>
<ABOVE LOGIC>
<ABOVE LOGIC>

:SetLockFile
::SET check for, and create lock file to ensure concurrent runs aren't possible
SET lockfile=\\server\share\lockfiles\my_pipe_program.lck
IF EXIST %lockfile% GOTO locked
::IF EXIST %lockfile% GOTO lockedrecheck 
ECHO This file is locked until current %~nx0 script ends or finishes using the EXE >> %lockfile%

ECHO "some logging information" | my_pipe_program >> %logfile% 2<&1

<More Logic>
<More Logic>
<More Logic>
<More Logic>

:end
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %logfile%
ECHO End: %date% at %time%                       >> %logfile%
ECHO ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ >> %logfile%
DEL /Q /F "%lockfile%"
ENDLOCAL
GOTO EOF

:locked
:: Come here to end the script since the lock file does exist
ECHO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>> %logfile%
ECHO LOCKED FILE: %~nx0 - %date% at %time%: FILE IS IN USE AND LOCKED                             >> %logfile%
ECHO + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +>> %logfile%
ENDLOCAL
GOTO EOF

:lockedrecheck
:: Come here to Pause the script with a loopback ping to nul for 3 minutes or roughly 180 seconds
PING 127.0.0.1 -n 180 > nul
GOTO :SetLockFile

2<&1 Example

echo "some logging information" | my_pipe_program >> logfile1.txt 2<&1
Pimp Juice IT
  • 1,010
  • 1
  • 9
  • 16
  • Using your method it is possible for 2 processes to check that the file exists, find that it does not, and proceed with unwanted consequences. Instead, don't test for existence, just use mkdir to (try to) create the lock as it is atomic, it either works and you get the lock or it fails. – user9517 Nov 28 '15 at 07:35
  • Using mkdir instead of your logic is a best practice. – user9517 Nov 28 '15 at 07:46
  • Please explain how I go about "Enabling advanced logging at this level to capture verbose detail or stack traces". These are simple CMD batch files, not a program I developed. I am more convinced that these errors are not the result of using the same file or program. While multiple CMD files can run concurrently, they do not use the same log files or programs that they pipe through. I don't think the problem is locking the execution of the CMD files, unless Windows itself is not able to support two CMD.EXE processes using piping or redirection at the same time. – tim11g Dec 03 '15 at 00:05
  • The my_pipe_program is a program I wrote. It is a console application in Delphi, and uses readln and writeln, expecting those to be stdin and stdout, respectively, when used in pipes. I'm not sure how to modify the program to provide additional logging or debugging. The error seems to come from the OS. My program does not see any error condition. – tim11g Dec 21 '15 at 22:46
  • I'm not a programmer and know basically nothing about Delphi language in particular. I'd ensure if the EXE you developed is called more than once and is currently running in memory on the machine that they both stay separate. Otherwise, what I suggested was a workaround to create a lock file to ensure only one instance of the EXE is run at a time from the same machine which the batch scripts call the EXE. Seeing that stack trace, capturing the error detail, etc. is something that'd be helpful in troubleshooting the issue otherwise regardless of it being an OS or memory issue you need evidence. – Pimp Juice IT Dec 22 '15 at 00:59