The Artima Developer Community
Sponsored Link

Legacy Java Answers Forum
October 2001

Advertisement

Advertisement

This page contains an archived post to the Java Answers Forum made prior to February 25, 2002. If you wish to participate in discussions, please visit the new Artima Forums.

Message:

The best way to use Runtime.exec() (on Windows, that is)

Posted by Matt Gerrans on October 28, 2001 at 4:36 PM


> So...how exactly should I call a program like Winamp and pass it a file to play? Should I use the the method shown in that URL (http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html)?
> Hiran

Hmm... Maybe I don't understand exactly what the problem is. It seems fairly straight-forward to me, especially in the case where you just want to launch a player or something, because all you have to do is launch it and forget about it. You would only get into all the streaming stuff mentioned in the article if you wanted to send input to and get output from a console app.

By the way, the article mistakenly asserts that if you want to do redireection, you must do it programmatically. Really, all you have to do is form the exec() string correctly. For instance, this works correctly: "c:\command.com /c echo Test 123 > c:\temp\exectest.txt" (try it in the app below and then check that the output file was created). I also fooled around a bit with it on Linux (I was trying "bash ls > file.txt" and stuff like that), but didn't get an output file (maybe a unix expert can offer a suggestion on this). It just may be that Linux requires the String array format of exec() -- more on that below.

As far as what I recommend, I'll give you my opinion for the Windows platform, where my expertise is: generally, it is better to do a "start file.mp3" than it is to try and launch a particular player. The start program is a little tool in Windows that kind of gives the effect of double-clicking the file in Explorer. If you use start, you'll get the player that the user has configured (for instance I may have MusicMatch installed, but I'd still rather have WinAmp be my default player).

Furthermore, if I wanted to do some more fancy stuff with executing programs on the windows platform, I'd have my Java program dynamically build a JavaScript (or JScript, really) that would handle the whole thing. JScript (and VBScript, but after learning object-oriented languages like C++, Java and Python I can no longer stomach aesthetically reprehensible BASIC language) is built into the system, so you don't have to do anything more than "start myscript.js" to run it. Also, JScript easily can hook into COM automation and therefore the Windows system, so it is probably better to do your dirty work that way, if possible, than to hose up your Java code with native methods. If you are working on the Windows platform, it is worth learning some JScript (unless you can find a Python module for the Windows Script Host! If you do, let me know!).

If you want to do all the input/output kind of thing discussed in the article and you don't know (and don't want to learn) JScript then it would be a good idea to wrap all that in a utility class. That would have the advantage of being a little more platform independent.

Below is a little app I wrote to facilitate fooling around with Runtime.exec(). You can run it as a console app (no GUI), or as a Swing application. As a console app, just specify the program to run, like so: "java ExecTester Notepad myfile.txt". If you run with no parameters, or with "/showui", the GUI will appear and you can try lots of exec()s there.

Note that I didn't bother with breaking the command into an array or adding environment stuff (as it works fine on the Windows platform as-is), but that could be done by someone with the time and ambition to do so. Then it would be more platform independent. Another addition, to make this thing complete would be adding all the process-monitoring stuff discussed in the article. I don't have time to do this, as I am still working on that homework assignment with the multiple grade options that I mentioned to Chin. (Maybe if one of these students requesting homework solutions does it, we can reciprocate by doing one of his/her homework assignments! :-)

- mfg


/**
* ExecTester.java
*
* Copyright 2001, by Matt Gerrans.
*/

// I suppose "import javax.swing.*" would be more succinct, but
// just in case your productivity is being meaasured by LOC:
import javax.swing.JTextField;
import javax.swing.JTextArea;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Container;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

/**
* A simple tester for Runtime.exec(). Could easily be adapted to
* testing other API calls (Hmm... maybe it shouldn't be called
* "ExecTester" in that case...). ExecTester runs as a console app
* (no GUI) or as a Swing application. You give no command line
* parameters, or the command line option /showui, the GUI will
* appear. Otherwise, it is assumed that the first parameter on
* command line is to be passed to Runtime.exec().
*
* Note (on Windows platform, for sure and I think also on unix
* platforms), if you want to include spaces (i.e. multipart
* command, as in a program to execute with parameters) you
* must put quotes around the whole thing, like so:
* java ExecTester "notepad c:\autoexec.bat"
* In case you didn't know it, that causes the whole thing to be
* packaged in args[0] (or argv[0] in C/C++).
*/
public class ExecTester
{
JTextField commandField;
JTextArea outputText;

/**
* Shows a simple Swing UI for testing exec(). This is handy when
* you want to try several different exec()s.
*/
public void showUI()
{
JFrame frame = new JFrame("Runtime.exec() Tester");

// frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
// Sun docs say use JFrame.EXIT_ON_CLOSE, but it doesn't exist,
// (in JDK 1.2, at least) so I'll add this window adapter:
frame.addWindowListener( new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);

Container pane = frame.getContentPane();
pane.setLayout( new java.awt.FlowLayout() );

pane.add(new JLabel("Enter your command:"));

commandField = new JTextField("notepad c:\\windows\\win.ini", 30);
pane.add(commandField);

final JButton goButton = new JButton("Execute It!");
pane.add(goButton);

goButton.addActionListener( new goButtonListener() );

pane.add( new JLabel( "Results of execution:" ) );
outputText = new JTextArea(5,50);
pane.add( new JScrollPane(outputText) );

frame.pack();
frame.setSize( 600, 200 );
// Yes, I'm ashamed of hard-coding the window size, but the default
// JFrame wasn't coming up nicely arranged. This could probably
// be fixed by fooling with more frames and layouts, but I'll leave
// that as an exercise for whomever wishes to pursue it.

frame.setVisible(true);
}

/**
* Runs the exec() and adds its output to the results area.
*/
class goButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
outputText.append( runExec( commandField.getText() ) );
}
}

/**
* Executes Runtime.exec() and returns the results is a
* human-readable string.
*
* @param cmd The command to send to Runtime.exec().
*/
public static String runExec( String cmd )
{
String results = "Results of Runtime.getRuntime().exec( \"" +
cmd + "\" ):";

try
{
Runtime.getRuntime().exec( cmd );
results += " No problem.";
}
catch( java.io.IOException e )
{
results += "\n " + e.toString();
}

return results + "\n";
}

/**
* Displays the UI or simply runs the command line, depending upon
* what's specified by args[0].
* @param args The usual thing.
*/
public static void main( String[] args )
{
if( args.length == 0 || args[0].equals( "/showui" ) )
(new ExecTester()).showUI();
else
System.out.println( "Runtime.getRuntime().exec( \"" +
args[0] + "\" ): " + runExec(args[0]));
}
}





Replies:
  • Thnx. Hiran October 28, 2001 at 8:33 PM (0)

Sponsored Links



Google
  Web Artima.com   
Copyright © 1996-2009 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us