PistolPete
PistolPete

Reputation: 784

Approach to implement Windows cmd communication - multiple commands

I'm trying to find a solution how to implement a multiple command - response interaction with the Windows cmd shell. Example:

  1. Start the cmd shell
  2. "dir"
  3. wait for and Handle input
  4. Execute new command depending on the input content
  5. wait for and Handle input
  6. etc.

PLEASE NOTE! Steps above were only to describe the way of communication, it is NOT my intention to browse the file system, i.e. the actual commands could be something else.

Approach so far:

try {            

        Runtime rt = Runtime.getRuntime();

        p = rt.exec("cmd");
        error = p.getErrorStream();
        input = p.getInputStream();
        output = new PrintStream(p.getOutputStream());            

        StreamGobbler errGobbler = new StreamGobbler(error, "ERROR");
        StreamGobbler inGobbler  = new StreamGobbler(input, "INPUT");

        errGobbler.start();
        inGobbler.start();

        output.println("dir");
        output.flush();

        sleep(5);

        output.println("dir");
        output.flush();
} catch (IOException e) {
        System.out.println(e.printStackTrace());
}

StreamGobbler class:

class StreamGobbler extends Thread
{
    InputStream is;
    String type;
    ArrayList<String> cmdRespArr = new ArrayList<String>();

    StreamGobbler(InputStream is, String type) {
        this.is  = is;
        this.type = type;
}

public void run() {

    try  {
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader bf = new BufferedReader(isr);
        String line = null;
        while ( ( line = bf.readLine() ) != null ) {
            cmdRespArr.add(line);
        }
    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
}

}

In this example however the while loop in the run method never returns between the issued commands (this is not part of the problem).

So, would the approach be to let the while method add the line read to a collection or other container, and then monitor that one for something indicating that the cmd shell is ready for input (which would in turn indicate that all available input from previous command have been read). And then fire off the next command?

In the example above this indication would get rid off the sleep call which right now is only there for debugging purposes.

I have a vague memory that this was the approach when doing it with Python.

Or is this totally wrong?

Upvotes: 2

Views: 251

Answers (1)

Grezgory
Grezgory

Reputation: 326

Will it be a solution to start multiple command processors, i.e. one per command?

I'm asking because with keeping one command processor open, it is very hard to determine when a command has been processed, unless you parse the output line by line and wait until you see the prompt in the output.

With multiple processors, i.e. executing "cmd /c dir" then input output redirs will close when the command has completed (and the associated process terminated).

Of course this will not work, if some commands depend on others, e.g. doing a chdir and expecting the next command to work in that dir.

Upvotes: 1

Related Questions