views:

1464

answers:

6

The Problem

I'm having a problem with a DOS batch file and labels. I keep getting this error:

The system cannot find the batch label specified

What I've tried

  • Two computers; a WindowsXP and a 2003 Server.
  • Made sure it was encoded as ASCII
  • Editted the hex code for the line continuation characters. Tried replacing all with CR , LF, and CRLF in turn. All combinations give me the same error.
  • Tried inserting extra characters before the label to make the label past 512 characters.

Here is the code:

cls
@echo off
SET zip=7za a dependencies.7z
call:dozip "c:\temp\dir.txt"

pause
goto exit

:dozip
  echo Testing 1.2.3...
  %zip% %1
goto:eof
:exit

Here's the hex with CRLF (0d 0a).

63 6c 73 0d 0a 53 45 54 20 7a 69 70 3d 37 7a 61 20 61 20 64 65 70 65 6e 64 65 6e 63 69 65 73 2e 37 7a 0d 0a 63 61 6c 6c 3a 64 6f 7a 69 70 20 22 63 3a 5c 74 65 6d 70 5c 64 69 72 2e 74 78 74 22 0d 0a 0d 0a 70 61 75 73 65 0d 0a 67 6f 74 6f 20 65 78 69 74 0d 0a 0d 0a 3a 64 6f 7a 69 70 0d 0a 20 20 65 63 68 6f 20 54 65 73 74 69 6e 67 20 31 2e 32 2e 33 2e 2e 2e 0d 0a 20 20 25 7a 69 70 25 20 25 31 0d 0a 67 6f 74 6f 3a 65 6f 66 0d 0a 3a 65 78 69 74

Here's the console's output (when I remove @echo off):

C:\>SET zip=7za a dependencies.7z

C:\>call:dozip "c:\temp\dir.txt"

C:\>echo Testing 1.2.3...
Testing 1.2.3...

C:\>7za a dependencies.7z "c:\temp\dir.txt"
The system cannot find the batch label specified - dozip

C:\>pause
Press any key to continue . . .

It never actually creates the 7zip file, so I think I can assume that its crashing on this line;

7za a dependencies.7z "c:\temp\dir.txt"

If I run that line by itself from a command prompt, it works fine and creates the dependencies.7z, so I don't think its necessarily a problem with 7za.exe.

I've already read this stackoverflow question: stackoverflow.com/questions/232651/why-the-system-cannot-find-the-batch-label-specified-is-thrown-even-if-label-ex

and the link from that post; help.wugnet.com/windows/system-find-batch-label-ftopict615555.html

The Answer

So, I found the problem guys.

I was using a technique I commonly use that I could only really describe as "proxy" batch files. I have a folder called c:\scripts, and I put several bat files in there to target commonly used exes. This saves my PATH variable from becoming absolutely massive with all of my command line tools. This way I only need to add c:\scripts to my PATH, and create a proxy batch file when I need something.

I had 7za.bat in c:\scripts, containing only this;

@echo off
"C:\Program Files\7-zip\7za.exe" %*

I changed my script to this;

SET zip="c:\program files\7-zip\7za.exe" a dependencies.7z

instead of this;

SET zip=7za a dependencies.7z

and it worked flawlessly.

The moral of the story...

Avoid calling other batch files from within a batch file.

A: 

Are you using Windows NT 4/Windows 2000? Only there can you use CALL to call subroutines within the same batch file.

Jacob
I've tried on both XP and 2003 which are NTbased.
csauve
+3  A: 

I would point out that the "Testing 1.2.3..." and "Press any key to continue . . ." lines indicate that execution has successfully gone to the :dozip label and then successfully returned to the caller.

Is the "7za" executable actually a batch file? If I modify my test script to have the helper be a batch file, I get the same error. The fix is to do 'call %zip% %1'

Andrew Medico
I will add the full output without the @echo off. That may shine some light on the situation.
csauve
Do you have a 7za.bat in your %path%? Anyway, try changing the "%zip% %1" line to "call %zip% %1".
Andrew Medico
Thanks Andrew, yes, 7za.bat was in my path, the problem was that I was using 7za.bat at all. See my "answer" section in my post.
csauve
Oh.. looks like parent actually answered it... silly me
csauve
A: 

Looking closely at your hex, it does not actually have all CRLF (0d 0a). Several lines end in LF-only (0a without a preceding 0d).

Check in your hex editor to make sure every 0a is preceded by 0d (exactly one).

Or just cut and paste your file into a blank Notepad document and re-save it.

system PAUSE
Thanks! I will try that. Maybe I missed one the last time I did my hex find/replace. I did it by eyeball so maybe I missed something.
csauve
I redid it, double and triple checking my CRLF's. Still doesn't work.63 6c 73 0d 0a 53 45 54 20 7a 69 70 3d 37 7a 61 20 61 20 64 65 70 65 6e 64 65 6e 63 69 65 73 2e 37 7a 0d 0a 63 61 6c 6c 3a 64 6f 7a 69 70 20 22 63 3a 5c 74 65 6d 70 5c 64 69 72 2e 74 78 74 22 0d 0a 0d 0a 70 61 75 73 65 0d 0a 67 6f 74 6f 20 65 78 69 74 0d 0a 0d 0a 3a 64 6f 7a 69 70 0d 0a 20 20 65 63 68 6f 20 54 65 73 74 69 6e 67 20 31 2e 32 2e 33 2e 2e 2e 0d 0a 20 20 25 7a 69 70 25 20 25 31 0d 0a 67 6f 74 6f 3a 65 6f 66 0d 0a 3a 65 78 69 74
csauve
A: 

FYI, full output without @echo off;

C:\>SET zip=7za a dependencies.7z

C:\>call:dozip "c:\temp\dir.txt"

C:\>echo Testing 1.2.3...
Testing 1.2.3...

C:\>7za a dependencies.7z "c:\temp\dir.txt"
The system cannot find the batch label specified - dozip

C:\>pause
Press any key to continue . . .

It never actually creates the 7zip file, so I think I can assume that its crashing on this line;

7za a dependencies.7z "c:\temp\dir.txt"

If I run that line by itself from a command prompt, it works fine and creates the dependencies.7z, so I don't think its necessarily a problem with 7za.exe.

csauve
@Galestar, feel free to edit your question to add this info. That way it will stay at the top, instead of being mixed in with the answers.
system PAUSE
Thanks system PAUSE, I added it
csauve
A: 

One possibility, although it seems unlikely, is that command extensions aren't enabled, or up-to-date, and this is interfering with call/goto/label behaviour.

Try:

echo [%cmdextversion%]

and if it's less than [2] (or empty -- []) then check to see if cmd.exe is being invoked with /e:off, or just run

cmd /e:on

in the console window where you will run this batch file.

system PAUSE
echo [%cmdextversion%] returns [2]
csauve
+2  A: 

the moral of the story: when calling external programs/batch files in a batch file, use call

call foo.bat

and/or

call %foo%

(Calling one batch from another has been done since the days of DOS, just remember to call)

Anders