Search code examples
javabatch-filecmdexitwindows-server-2016

exit /b 0 returns 1 in process.exitValue if run as non-admin on Windows Server 2016


I have the following java class and a batch file.

testc.java:

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Map;

public class testc {
public static void main(String[] mainargs) {
        System.out.println("Java class initiated");
        try {
            String line;
            ArrayList<String> args = new ArrayList<String>();
            String script = "script-util.bat";
            args.add(script);
            ProcessBuilder pb = new ProcessBuilder(args);
            Map<String, String> env = pb.environment();
            System.out.println("Starting batch file");
            Process process = pb.start();
            InputStream is = process.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            while (null != (line = reader.readLine())) {
                System.out.println("OUT: " + line);
            }
            System.out.println("Waiting for complete exit");
            int returnCodeW = process.waitFor();
            int returnCodeE = process.exitValue();
            System.out.println("returnCodeW: " + returnCodeW);
            System.out.println("returnCodeE: " + returnCodeE);
        }
        catch (Throwable t) {
            System.out.println("Exception caught");
        }
    }
}

content of script-util.bat is just one line,

case 1:

exit /B 0

case 2:

exit /B 2

case 3:

exit 0

case 4:

exit 2

case 5:

rem exit 0

Output for "java testc" with batch file having content from case 1 when run in a non-evevated command prompt:

c:\javatest2>java testc
Java class initiated
Starting batch file
OUT:
OUT: c:\javatest2>exit /B 0
Waiting for complete exit
returnCodeW: 1
returnCodeE: 1

Output for case 5 returns code 1 instead of 0 too. Output for any other cases, or all cases when run from the same working directory in an elevated command prompt reflects correct errorlevel code.

My question is why exit code returns 1 instead of 0 if not run as admin?

Environment: Windows Server 2016 x64, JDK 1.8

Edit: This issue seems to be environment specific. One installation of Windows Server 2016 10.0.14393 using JDK 1.8 u151 behaves as above while another one of the same builds does not. Anyway this is not expected under any environment.


Solution

  • In cooperation with the customer we found out the cause. The system was using a shell script to put different color to cmd window if the user opening it has administrative rights at that time. The command causing exit code to change is included in a custom script shell_color.cmd:

        @echo off
        rem The following line is the root cause
        bcdedit 1>NUL 2>&1
        rem bcdedit returns exit code 1 for some reason when run as non-admin
        if %errorlevel%==1 goto user
        color 4f
        goto end
        :user
        color 0f
        :end
    

    and Windows registry needs this script to be referenced in the following way:

        [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]
        "autorun"="%windir%\\system32\\shell_color.cmd"