Search code examples
batch-fileteraterm

Using teraterm API call 'setexitcode' to set WIndows system variable %errorlevel% requires 2 teraterm sessions to register


The following 4 files can be used to demonstrate the problem I am seeing: (each simplified for readability.)

temp1.bat:

@echo off
start /w ttpmacro.exe c:\temp\temp.ttl 0 
start /w ttpmacro.exe c:\temp\no_op.ttl && if %errorlevel% EQU 0 (echo PASS ) Else ( Echo TIMEOUT )

temp2.bat:

@echo off
start /w ttpmacro.exe c:\temp\temp.ttl 1 && if %errorlevel% EQU 0 (echo PASS ) Else ( Echo TIMEOUT )  

Note: the digit following c:\temp\temp.ttl (eg a 1 or 0 in these examples.) is a command line paramter, an is referred to as param2 within the script.

temp.ttl

str2int num param2
setexitcode num  

no_op.ttl

;Do nothing
num = 0  

Running temp1.bat from a Windows CMD prompt, the comparison statement yields the expected response each time, consistently.

Running temp2.bat from a Windows CMD prompt, the comparison statement result is consistently unexpected after the first run, but when called a second time yields the expected result.

The problem I am having is that Windows does not seem to register the value into its %errorlevel% variable upon exiting a single instance of a teraterm script. I have to run a subsequest script (eg. no-op.ttl) before the %errorlevel% variable is updated, and the comparison test yields the expected results.

Can someone identify how I can have the Windows %errorlevel% variable updated correctly after running a single instance of the Tera Term script?

Additional information on key items in Tera Term script and batch files:

Usage - TTPMACRO

setexitcode (From the Tera Term API reference documentation.) enables a script to return a value to the calling process, eg in this case a CMD window. I am using this returned value to make determine within Windows, that all internal script steps were executed correctly. (all but those lines essential for this question have been removed.)

And, usage information on Errorlevel states:

A preferred method of checking Errorlevels is to use the %ERRORLEVEL% variable:

IF %ERRORLEVEL% NEQ 0 Echo An error was found
IF %ERRORLEVEL% EQU 0 Echo No error found

IF %ERRORLEVEL% EQU 0 (Echo No error found) ELSE (Echo An error was found)
IF %ERRORLEVEL% EQU 0 Echo No error found || Echo An error was found

Solution

  • start /w ttpmacro.exe c:\temp\temp.ttl 1 && if errorlevel 1 (echo TIMEOUT ) Else ( Echo PASS ) 
    

    When cmd parses a block of code, it replaces any %var% with the current value of that variable and then executes the code.

    Consequently, %errorlevel% is being replaced by the value returned by the previous run.

    This is the conventional way of using errorlevel - IF ERRORLEVEL n is TRUE if the runtime (ie. current) errorlevel is n or greater than n. IF ERRORLEVEL 0 is therefore always true. IF NOT ERRORLEVEL 1 is a test for errorlevel=0. So is IF %ERRORLEVEL%==0, except that the former can be used within a block but the latter cannot.

    There are many items on SO about delayedexpansion - another method that could be used.