JAVA [Elaboration] Analysis RunTime error from the bottom, Cmd command execution is normal

Du Jinyang, the Superman of Ottoman, once said, "It is better to perish outside the law than to live in it."



Maybe you will often encounter the following problems in development, but Baidu Google can not come out, bloggers trample on the pit to share with you:

  • Error CreateProcess error=2, ______________________
  • JAVA cmd execution failure JAVA
  • RunTime reported an error, but performed normally under cmd
  • ProcessBuilder exception CreateProcess error=2, ______________________
  • JAVA CMD.EXE/C Problems


    Here is a record of these problems, recently encountered a more abnormal problem, here is to do Android multi-channel packaging, which involves unpacking, back-up and so on...
    _The main problem encountered is the incoming parameters, how the space is not good, tossed about all morning, and then read the underlying code before finalizing, first to summarize the process and methods of solving.

    1. Suppose you want to execute the command of cmd.exe/C, remember that if you execute something like external.exe.bat, you must not add CMD/C to the array. If you do, you will fail to execute the command!

    2. Assuming you're going to execute multiple parameters, remember, don't learn that blogs on the Internet add "" before array commands, which will force you.

    3. Suppose you want to execute multiple parameters, not to go blank like Cmd on PC. I tried before, and found the underlying source code that can't be seen. The underlying source code will read the blank space and replace it with ", and the underlying source code will be pasted out.

    4. Finally, as long as the parameters are passed in and replaced, do not take the initiative to go blank!

1. CreateProcess error=2, ______________________

_There are two common ways to report this error. The common way is to call external exe directly after using CMD.EXE C.

//Execution code
Runtime.getRuntime().exec(cmds);
  • First: the error parameter passed in here: "D:/dujinyang/immqy.exe"
    d","k","D:/dujinyang/immqy_new". Why does this happen? Because if there are spaces between instructions and they are separated by different strings, instructions cannot be recognized.

  • The second is that the parameters passed in here are all right, only bit errors, so the error is reported. At this time, it is necessary to change to other commands to try this error. Moreover, CMD/C
    Received is the default parameter, if with exe, will be identified as a program, if with parameters, unless bat can receive directly, otherwise it will only be treated as a program, if apktool also occurs here.


2. Failure of cmd execution

  • The first one is parameter error. Needless to say, the solution is to replace your own parameters in the string [] group to test if you test OK and restore placeholders.
  • The second type: placeholder error, solution, or replacement parameters to test.

    Example:

//Correct code
String[] CMD_APKTOOL_D = new String [] { "CMD.EXE", "/C","%1","d","-f","%2","-o","%3"};//decompression


/**The following are all error codes**/

String[] CMD_APKTOOL_D = new String [] { "CMD.EXE", "/C"," %1"," d"," -f"," %2"," -o","%3"};//decompression

String[] CMD_APKTOOL_D = new String [] { "CMD.EXE", "/C","%1"," d "," -f ","%2"," -o","%3"};//decompression

String[] CMD_APKTOOL_D = new String [] { "CMD.EXE", "/C","%1","","d","","-f","","%2","","-o","","%3"};//decompression


3. Source code analysis

_Why are there so many errors and so many problems with space characters? Check the API related to Process Builder. JAVA RUNTIME has seen everything and found no problems. In the process of debugging, we found a piece of code in Process Impl. class. Look at the figure below.

/*
 * @(#)ProcessImpl.java 1.32 06/03/22
 *
 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

package java.lang;

import java.io.*;

/* This class is for the exclusive use of ProcessBuilder.start() to
 * create new processes.
 *
 * @author Martin Buchholz
 * @version 1.32, 06/03/22
 * @since   1.5
 */

final class ProcessImpl extends Process {

    // System-dependent portion of ProcessBuilder.start()
    static Process start(String cmdarray[],
             java.util.Map<String,String> environment,
             String dir,
             boolean redirectErrorStream)
    throws IOException
    {
    String envblock = ProcessEnvironment.toEnvironmentBlock(environment);
    return new ProcessImpl(cmdarray, envblock, dir, redirectErrorStream);
    }

    private long handle = 0;
    private FileDescriptor stdin_fd;
    private FileDescriptor stdout_fd;
    private FileDescriptor stderr_fd;
    private OutputStream stdin_stream;
    private InputStream stdout_stream;
    private InputStream stderr_stream;

    private ProcessImpl(String cmd[],
            String envblock,
            String path,
            boolean redirectErrorStream)
    throws IOException
    {
    // Win32 CreateProcess requires cmd[0] to be normalized
    cmd[0] = new File(cmd[0]).getPath();

    StringBuilder cmdbuf = new StringBuilder(80);
    for (int i = 0; i < cmd.length; i++) {
            if (i > 0) {
                cmdbuf.append(' ');
            }
        String s = cmd[i];
        if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
            if (s.charAt(0) != '"') {
            cmdbuf.append('"');
            cmdbuf.append(s);
            if (s.endsWith("\\")) {
            cmdbuf.append("\\");
            }
            cmdbuf.append('"');
                } else if (s.endsWith("\"")) {
            /* The argument has already been quoted. */
            cmdbuf.append(s);
        } else {
            /* Unmatched quote for the argument. */
            throw new IllegalArgumentException();
        }
        } else {
            cmdbuf.append(s);
        }
    }
    String cmdstr = cmdbuf.toString();

    stdin_fd  = new FileDescriptor();
    stdout_fd = new FileDescriptor();
    stderr_fd = new FileDescriptor();

    handle = create(cmdstr, envblock, path, redirectErrorStream,
            stdin_fd, stdout_fd, stderr_fd);

    java.security.AccessController.doPrivileged(
        new java.security.PrivilegedAction() {
        public Object run() {
        stdin_stream =
            new BufferedOutputStream(new FileOutputStream(stdin_fd));
        stdout_stream =
            new BufferedInputStream(new FileInputStream(stdout_fd));
        stderr_stream =
            new FileInputStream(stderr_fd);
        return null;
        }
    });
    }

    public OutputStream getOutputStream() {
    return stdin_stream;
    }

    public InputStream getInputStream() {
    return stdout_stream;
    }

    public InputStream getErrorStream() {
    return stderr_stream;
    }

    public void finalize() {
    close();
    }

    public native int exitValue();
    public native int waitFor();
    public native void destroy();

    private native long create(String cmdstr,
                   String envblock,
                   String dir,
                   boolean redirectErrorStream,
                   FileDescriptor in_fd,
                   FileDescriptor out_fd,
                   FileDescriptor err_fd)
    throws IOException;

    private native void close();
}



So refining this code and printing it out, we can find that the big problem is in S. indexOf ('') >= 0 here, then we can change this code to achieve output, the code is as follows

    /**
     * Simulate the underlying CMD to achieve output view command line
     * @see ProcessImple.class
     * @author KARL-dujinyang
     * @param cmd
     * @return
     */
    public static String processImpl(String [] cmd){
        System.out.println("dujinyang start");
        StringBuilder cmdbuf = new StringBuilder(80);
        for (int i = 0; i < cmd.length; i++) {
                if (i > 0) {
                    cmdbuf.append(' ');
                }
            String s = cmd[i];
            if (s.indexOf(' ') >= 0 || s.indexOf('\t') >= 0) {
                if (s.charAt(0) != '"') {
                cmdbuf.append('"');
                cmdbuf.append(s);
                if (s.endsWith("\\")) {
                cmdbuf.append("\\");
                }
                cmdbuf.append('"');
                    } else if (s.endsWith("\"")) {
                /* The argument has already been quoted. */
                cmdbuf.append(s);
            } else {
                /* Unmatched quote for the argument. */
                throw new IllegalArgumentException();
            }
            } else {
                cmdbuf.append(s);
            }
        }
        System.out.println(cmdbuf.toString());
        System.out.println("dujinyang end");
    }



Finally, execute the correct String [] array and find that there is no problem, fix it! If the test is added with "CMD.EXE" and "/C", it will fail to execute.



I'll share the code to execute the command.~


|| Copyright Statement: This is an original article by blogger Du Jinyang. Please indicate the source for reprinting.

If you have other questions, leave a message or join the Android mobile technology elite group (2462 31638)

Keywords: Java Android Google Mobile

Added by skroks609 on Sun, 14 Jul 2019 23:42:17 +0300