1.

Solve : Help with File Open ErrorLevel in a DOS Batch?

Answer»

Hello, I've got a simple batch file that's running on a windows xp system and it's set to run a continuous loop looking for files to exist in a particular folder on my network DRIVE. The bat file basically consists of a bunch of IF EXIST commands see example below.
Code: [Select]:Loop
IF EXIST FILENAME1 GOTO JOB1
IF EXIST FILENAME2 GOTO JOB2
IF EXIST FILENAME3 GOTO JOB3
Goto Loop

:job1
run commands
Goto loop

:Job2
run commands
Goto loop

:Job3
run commands
Goto loop

This works but from time to time the batch encounters an open file that's being written to the network drive and it cause's all sorts of problems as you might imagine. I'm not very good with DOS IF statements etc so I can't figure out a way to do a simple test on the file after the IF EXIST command to see if it's OPEN or NOT and then either doing the GOTO Loop or GOTO Job#..

Thanks for your help...Scott Some people suggest trying to rename the file (and renaming it BACK if successful) but that doesn't always provide a true test of an open file, whereas COPY /B filename+NUL filename is more reliable (and does not alter the file!)

:loop
if exist filename1 COPY /B filename1+NUL filename1 > NUL 2>&1 && (GOTO Job1)
if exist filename2 COPY /B filename2+NUL filename2 > NUL 2>&1 && (GOTO Job2)
if exist filename3 COPY /B filename3+NUL filename3 > NUL 2>&1 && (GOTO Job3)
Goto loop

Thanks for the reply..

Do I need to clean up the file I'm coping too so the next time this file Exists and the copy command is invoked there won't be a problem over writing that file..

Thanks again for your help..
This is simpler to LOOK at, and should work the same...

:loop
if exist filename1 COPY /B filename1+NUL filename1 > NUL 2>&1 && (GOTO Job1)
if exist filename2 COPY /B filename2+NUL filename2 > NUL 2>&1 && (GOTO Job2)
if exist filename3 COPY /B filename3+NUL filename3 > NUL 2>&1 && (GOTO Job3)
Goto loop


Quote

Do I need to clean up the file I'm coping too so the next time this file Exists and the copy command is invoked there won't be a problem over writing that file..

Not sure what you mean here...

Thanks again for your help..

I don't exactly understand what this command is doing COPY /B filename1+NUL filename1 > NUL 2>&1 && ..

I see the COPY command so I assume that it's creating a file somewhere on my network drive so I was wondering if I needed to DELETE the copied file to keep the drive cleaned up to prevent other issues like over write errors etc the next time the loop condition exists..

Sorry for the dumb questions...There are no extra files produced. The way the test works is this:

What you are doing is copying each file onto itself. Normally you cannot copy a file to another file in the same folder with the same name. You get an error, "The file cannot be copied onto itself." You can try it yourself at the prompt. Say you have a file called test.txt. If you do...

copy test.txt test.txt

you get the error.

So you use a trick. NUL is a special empty file available in may operating systems including Windows. So you use the COPY file1+file2 file3 syntax, where the + sign means copy file1 and file2 to file3. The trick is that NUL is an empty file so copying file1+NUL to file2 just makes a copy of file1 in file2. A further trick is that this works if file2 already exists. So we copy file1+NUL to file1 (that is, itself, note the files are the same) We use the /B switch after COPY to force a binary (byte for byte copy) so that nothing in the file gets altered. If the file is not in use by another process, the operation succeeds and the file ends up the same as it was before. If the file is in use, the operation fails. We can test for failure or success using && and ||.

command1 && command2 - only if command1 was successful (errorlevel 0) then command2 is executed.

You have your loop going round and round testing if each file is in use. If it is in use, you would get an error message each time saying "The process cannot access the file because it is being used by another process." If the file was not in use, you would get a "1 file(s) copied" message. Either way, these would clutter up the screen each time so, using > we we redirect the console output stream to another instance of NUL (yes, you can do this!) also we use 2>&1 to redirect the (STDERR, stream 2) into the standard console stream (STDOUT, stream 1). So there are no messages on the screen.

I know this may seem confusing, but you can look on the web for explanations of the COPY command, NUL, stream REDIRECTION, as well as the && and || operators.Thank you for the detailed explanation I really appreciate your time and effort... This is exactly what I was looking for..

Thanks again for all of your help and guidance..

ScottAnother option from Dbenham on StackOverFlow.
http://stackoverflow.com/questions/10518151/how-to-check-in-command-line-if-given-file-or-directory-is-locked-that-it-is-usOne thing to be aware of is that in any multitasking operating system, there is no 100% foolproof way of knowing that a file is not in use, at the time you want to do something to it. You could do a check that comes back "not in use" and then, milliseconds later, before your script has a chance to do the next command, the file gets grabbed by another process. No matter how careful you are there is always a window between when you check if the file is available and when you actually use it. This may not pose much of a problem e.g. if you are looking to if an expected file exist in a folder, you find that it does, but the process that was writing it has not yet finished, and you know that after that happens, no other process is going to grab it.



Discussion

No Comment Found