Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 4 of 4

Thread: Windows Cmd Prompt streams

  1. #1
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Windows Cmd Prompt streams

    The ultimate goal of the project I'm currently working on is to create a Swing command prompt which uses Window's Cmd prompt to execute commands. I have the swing portion finished, now I just need to stream input/output between my Java program and the command prompt.

    Now I want the underlying functionality of this command prompt to be fairly similar to what the real thing will do (granted with a few exceptions, these are kind of irrelevant in this topic), which involves supporting stuff like batch files and the set command.

    It isn't a problem to get one single command to work (or even running a bunch of commands in a batch file), but I'm having problems getting multiple user-entered commands to work.

    For example:

    SET IS_OK=1
    IF IS_OK EQU 1 (ECHO "It is ok.")
    ECHO "DONE"

    The expected output if a user were to type this into a real command prompt would be to print out "It is ok.", followed by "DONE" (without quotes)

    The way I currently have it setup is to run a new command prompt for every command. This automatically dis-allows the above from working because set only works in an individual's environment variable.

    Here's a short example of what I'm doing:

    import java.io.IOException;
    import java.util.Scanner;
     
    public class Test
    {
        public static void main(String[] args) throws IOException, InterruptedException
        {
            runWndCommand("SET IS_OK=1");
            runWndCommand("IF IS_OK EQU 1 (ECHO It is ok.)");
            runWndCommand("ECHO DONE");
        }
     
        /**
         * runs a Windows command prompt with the given command. Output is printed
         * out to System.out. Not entirely robust, but it demonstrates the point.
         * 
         * @param cmd
         * @throws IOException
         * @throws InterruptedException
         */
        public static void runWndCommand(String cmd) throws IOException, InterruptedException
        {
            Runtime runtime = Runtime.getRuntime();
            Process p = runtime.exec(new String[] { "cmd.exe", "/C", cmd });
     
            Scanner reader = new Scanner(p.getInputStream());
            while (reader.hasNext())
            {
                System.out.println(reader.nextLine());
            }
            p.waitFor();
        }
    }

    The output of this code is to only print out "DONE"

    Before you start saying that I could pass multiple commands in the runtime.exec() call, remember that this is for a command prompt. As such, individual calls are very likely to be executed before the next command would even be entered.

    Is something like this even possible to do (without resorting to JNI, JVM mods, etc.)?

    I've tried piping input to the command process using p.getOutputStream() (and running the command prompt without the /C flag), but the command prompt doesn't seem to respond to any inputs I put through this stream.

    Oh, and I would really prefer not to re-write the windows command prompt functionality all in Java.

    cross-posted at Cmd process streams - Java Forums.


  2. #2
    Administrator copeg's Avatar
    Join Date
    Oct 2009
    Location
    US
    Posts
    5,267
    Thanks
    176
    Thanked 821 Times in 764 Posts
    Blog Entries
    5

    Default Re: Windows Cmd Prompt streams

    Have you tried keeping the Process open before running the next command? For example retrieve the Input and Output streams of the Process, pipe those commands to the OutputSteam, and do both input/output in their own threads? I'm not sure this will work, but its worth a quick try.

  3. #3
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Windows Cmd Prompt streams

    Yes, I've tried getting the input/output streams, but it's not processing any inputs I'm sending. I think the problem is because I can't think of any good way to send a "return" signal to indicate that a complete statement has been entered. I can send the '\n' character (or \r\n sequence), as well as the -1 byte value (which is used in some Java streams to denote the end of a read sequence), but none of these have the desired effect.

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
     
    public class Test
    {
        public static void main(String[] args) throws IOException, InterruptedException
        {
            cmd = Runtime.getRuntime().exec("cmd.exe");
            cmdOutput = cmd.getInputStream();
            cmdInput = cmd.getOutputStream();
            Thread display = new Thread(new StreamGobbler(cmdOutput, ""));
            display.setDaemon(true);
            display.start();
            runWndCommand("SET IS_OK=1");
            runWndCommand("IF IS_OK EQU 1 (ECHO It is ok.)");
            runWndCommand("ECHO DONE");
            runWndCommand("EXIT");
            cmd.waitFor();
        }
     
        private static Process        cmd;
        private static InputStream    cmdOutput;
        private static OutputStream    cmdInput;
     
        /**
         * runs a Windows command prompt with the given command. Output is printed
         * out to System.out
         * 
         * @param cmd
         * @throws IOException
         * @throws InterruptedException
         */
        public static void runWndCommand(String cmd) throws IOException, InterruptedException
        {
            System.out.println("input> " + cmd);
            for (int i = 0; i < cmd.length(); ++i)
            {
                cmdInput.write(cmd.charAt(i));
            }
            cmdInput.write('\r');
            cmdInput.write('\n');
            cmdInput.write(new byte[] { -1 });
        }
    }

    Here's the stream gobbler class. It basically just prints out all inputs it can read from the stream to System.out, but does so on a separate thread.

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
     
    class StreamGobbler extends Thread
    {
        InputStream    is;
        String        type;
     
        StreamGobbler(InputStream is, String type)
        {
            this.is = is;
            this.type = type;
        }
     
        @Override
        public void run()
        {
            try
            {
                InputStreamReader isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                String line = null;
                while ((line = br.readLine()) != null)
                {
                    System.out.println(type + ">" + line);
                }
            }
            catch (IOException ioe)
            {
                ioe.printStackTrace();
            }
        }
    }

    edit:

    I was wondering, what about using a Java robot? I can only seem to be able to attach the robot to a particular GraphicsDevice, but Runtime.exec() doesn't provide a cmd prompt terminal window (also, such a window is not desired). Is it possible to send the key event to a particular process even though it doesn't have a windows handle (and is focused)?
    Last edited by helloworld922; October 25th, 2010 at 08:28 PM.

  4. #4
    Super Moderator helloworld922's Avatar
    Join Date
    Jun 2009
    Posts
    2,896
    Thanks
    23
    Thanked 619 Times in 561 Posts
    Blog Entries
    18

    Default Re: Windows Cmd Prompt streams

    Finally solved my problem! I forgot to flush the cmdInput stream (writing the newline character is also important) Just in case anyone wants, here's the code that works:

    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintStream;
     
    public class Test
    {
    	public static void main(String[] args) throws IOException, InterruptedException
    	{
    		cmd = Runtime.getRuntime().exec("cmd");
    		cmdOutput = new BufferedInputStream(cmd.getInputStream());
    		cmdInput = new PrintStream(new BufferedOutputStream(cmd.getOutputStream()));
    		Thread display = new Thread(new StreamGobbler(cmdOutput, ""));
    		display.setDaemon(true);
    		display.start();
    		runWndCommand("set IS_OK=\"1\"");
    		runWndCommand("echo %IS_OK%");
    		runWndCommand("EXIT");
    		cmd.waitFor();
    	}
     
    	private static Process		cmd;
    	private static InputStream	cmdOutput;
    	private static PrintStream	cmdInput;
     
    	/**
    	 * runs a Windows command prompt with the given command. Output is printed
    	 * out to System.out
    	 * 
    	 * @param cmd
    	 * @throws IOException
    	 * @throws InterruptedException
    	 */
    	public static void runWndCommand(String cmd) throws IOException, InterruptedException
    	{
    		cmdInput.println(cmd);
    		cmdInput.flush();
    	}
    }

Similar Threads

  1. [SOLVED] can't run javac directly from command prompt
    By epezhman in forum Java IDEs
    Replies: 7
    Last Post: January 12th, 2011, 06:38 PM
  2. Strange launch problem using command prompt
    By Asido in forum Java Theory & Questions
    Replies: 2
    Last Post: September 15th, 2010, 07:52 AM
  3. data and object streams
    By bbr201 in forum Java Theory & Questions
    Replies: 4
    Last Post: July 16th, 2010, 06:18 PM
  4. how do I keep a persistent prompt in JTextArea and allow user input
    By cazmo in forum What's Wrong With My Code?
    Replies: 2
    Last Post: February 23rd, 2010, 12:14 PM
  5. reading JMF input streams?
    By wolfgar in forum File I/O & Other I/O Streams
    Replies: 0
    Last Post: January 11th, 2010, 11:22 PM