0

I would like to know if its possible to run cmd through Java. Not just one command at a time but a continuous stream of user input commands that relays the info received. Is this possible or should I just stop trying now?

I'm not sure why I'm attaching this; it's not very relevant, but this is what I was trying to accomplish this with. However, it resets the cmd after every command. (Yes, I realize this is bad coding, but I'm just attempting something my boss asked about.)

import java.io.*;
import java.util.Scanner;

public class Cmd {

    public static void main(String[] args) throws IOException {

        String line;

        while (true) {
            Scanner scanner = new Scanner(System.in);
            String comm = scanner.nextLine();
            ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", comm);
            builder.redirectErrorStream(true);
            Process p = builder.start();
            BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));

            while (true) {
            line = r.readLine();
            if(line==null){break;}
                System.out.println(line);
           }
       }
   }
}

Basically, cmd but behind a Java GUI with user input commands is my end game. If anyone could tell me if this is possible and if so point me in the right direction I would be grateful.

asteri
  • 11,402
  • 13
  • 60
  • 84
Dax
  • 3
  • 1
  • Does this: http://stackoverflow.com/questions/10293627/how-to-use-java-lang-process-class-to-provide-inputs-to-another-process answer your question? – bas Jul 31 '13 at 18:59
  • Also, you can use `Desktop.getDesktop().open(new File("path/to/cmd"));` – Azad Jul 31 '13 at 19:04

1 Answers1

0

Yes, it is possible.

At the end of my answer is an example program. It is far from perfect and is missing some implementation details. For example proper exception handling and also detect when the cmd has exited... But it may be used as a starting point.

In essence the solution to your question is to start cmd.exe as a new Process. Then read commands in java from standard input stream (System.in) and pipe it to the cmd.exe-process. To provide feedback to the user you must read the standard output from cmd.exe-process and print it to the standard output of your java process (System.out). Also read standard error from cmd.exe-process and print it to standard error of your java process (System.err).

Close all resources when you are done. I indicated this in the example, but this is not production ready. Any exception would prevent the example program from cleaning up.

Another implementation detail: The example program uses a second thread to read output from cmd.exe-process. Otherwise you will only get output when the user hits enter.

Finally, here is the code:

package com.example;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

public class JavaCmd {

    /**
     * @param args
     * @throws IOException 
     */
    public static void main(String[] args) throws IOException {
        ProcessBuilder procBuilder = new ProcessBuilder("cmd.exe");
        Process proc = procBuilder.start();
        PrintWriter outToProc = new PrintWriter(proc.getOutputStream());
        final BufferedReader inFromProc = new BufferedReader(new InputStreamReader(proc.getInputStream()));
        final BufferedReader errorFromProc = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        Thread outputThread = new Thread(new Runnable(){
            @Override
            public void run() {
                while(true) {
                    try {
                        while(inFromProc.ready()) {
                            String line = inFromProc.readLine();
                            System.out.println(line);
                        }
                        while(errorFromProc.ready()) {
                            String line = errorFromProc.readLine();
                            System.err.println(line);
                        }
                    } catch (IOException e) {
                        throw new RuntimeException("Error in output thread", e);
                    }
                    try {
                        Thread.sleep(100);
                    } catch(InterruptedException e) {
                        System.out.println("Output Thread interrupted -> Thread will terminate");
                        break;
                    }
                }
            }
        });

        outputThread.start();
        System.out.println("\n\nProxy shell is ready. Enter 'quit' to leave program.\n\n");
        System.out.flush();
        String line = null;
        while((line = reader.readLine()) != null) {
            if(line.equalsIgnoreCase("quit")) {
                System.out.println("Good Bye");
                break;
            }
            outToProc.println(line);
            outToProc.flush();
        }
        reader.close();
        outputThread.interrupt();
        proc.destroy();
    }

}
David
  • 1,204
  • 12
  • 16