Executing a Windows command line command - java

Here is an overview of what I am doing. I have a Java Swing application. On it I have a button called 'Ping'. What I want to happen is that when I click on the button Ping then it should ping a particular server. The server IPAddress details are in a text box.
So this is the code I have.
try {
Process p = Runtime.getRuntime().exec(strbf.toString());
if (Action.equalsIgnoreCase("PING"))
{
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = in.readLine()) != null)
{
mylogger.logInfo("Servers", "actionToBeTaken", "Ping line is" + line);
}
}
So the output of the ping goes into a logger file. Everything is good so far. But I don't want this behavior. Note that if I type in ping into the windows run prompt or dos prompt then a seperate ping window pops up. This is the way I want my code to function. Click on a button and the window automatically pops up. What changes do I make to my code? I tried different things but it does not seem to work. For example the below does not work. I don't know where the output of the ping command is getting eaten up. How do I ensure the command prompt windows pops up and the ping output is visible there.
try {
if (Action.equalsIgnoreCase("PING"))
{
Runtime.getRuntime().exec(strbf.toString());
}

Related

Bring control from application to java frame

I use a java program for communication between a arduino board and a scratch file. The communication happen well. I use a user interface to start the communication where i have buttons called
connect
close and minimize
When the user clicks the connect button code will check the value in combo box and accordingly it opens the scratch file.
Once the connect button is clicked the control moves to the scratch application. After completing my work when i tried closing the scratch. My scratch application closes as expected but the control does not return to the user interface because of which i am not able to close the application and i close it in net beans forcefully. In the output screen i don't see build successful and instead i get build stopped. That is my process works perfectly until i give connect but once the button is pressed it is hanged up some where.
I tried making it as a jar file and running it in a different machine at that time i use end task in task manager to close the application.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
if("Disconnect".equals(jButton1.getText()))
{
System.exit(0);
}
if(jComboBox2.getSelectedItem()==null)
{
System.out.println("Select one port");
}
else
{
Runtime r = Runtime.getRuntime();
try {
//this.hide();
//p = r.exec("C:\\Program Files\\Scratch 2\\Scratch 2.exe C:\\Users\\Admin\\Desktop\\fwdbckpwm12.sb2");
p = Runtime.getRuntime().exec("C:\\Program Files\\Scratch 2\\Scratch 2.exe C:\\Users\\Admin\\Desktop\\scratch files new.sb2");
//Runtime.getRuntime().exec("taskkill /F /IM <p>.exe");
//p.destroy();
//r.exec("C:\\Windows\\notepad.exe C:\\Windows\\ss.txt");
//this.setDefaultCloseOperation(EXIT_ON_CLOSE);
A4S a4sObj = new A4S(new String[] {jComboBox2.getSelectedItem().toString()}); //defaultline
//A4S a4sObj = new A4S(new String[]{"COM16"}); //addedline
//r.gc();
//this.setDefaultCloseOperation(EXIT_ON_CLOSE);
} catch (IOException ex) {
Logger.getLogger(serialportselection.class.getName()).log(Level.SEVERE, null, ex);
}
finally{
//p.destroy();
//System.gc();
// }
}
Here is the code i tried. But none seems to work.
Move all Process related work into separate Thread.
Use waitFor method to recognise Process end - then you are free to
exit your app.
As I can understood you used SWING for creating UI.
You can set
yourFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
for your frame. This must help.

How to close a windows explorer?

I have a code that uses jDesktop to open a windows explorer interface when I clicked the button LOGIN and it's working right..
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
Desktop desktop = Desktop.getDesktop();
File dirToOpen;
try {
dirToOpen = new File("C://as//2010-0000-1");
desktop.open(dirToOpen);
} catch (IOException ex) {
ex.getMessage();
} catch (IllegalArgumentException iae) {
System.out.println("File Not Found");
}
}
then now, my problem is when I click the button LOGOUT, the jDesktop windows explorer interface should also be closed... I dont know what codes to use....
This is not so simple, they only chance you have is if you have a reference to the process in question. This is going to mean you're going to need to take more control over the process...This also means that it will only work on Windows...
I use the following code to show a specified file in Windows Explorer...
String path = file.getCanonicalPath();
ProcessBuilder pb = new ProcessBuilder("explorer.exe", "/select," + path);
pb.redirectError();
Process proc = pb.start();
Once you have access to the Process, you can try using Process#destory to try and terminate the process.
Launching the process should be done from a separate thread, so you don't get yourself all tied up in a block point, you should also consume the Process's output just incase it causes the process to stall.
ps- I don't have access to a Windows machine at the moment, so I'm not sure if Process#destory will work ;)

JProgressBar to keep track of a Native(C++) application using JNI

I have a c++ application which runs for a long time and I want to track the progress of it. I have a user interface for this application in java. Can anyone please tell me how to track the progress of the native application using JProgressBar. My native application returns an integer when it is done and I have a "Done" button that shows up when this integer is returned. But I want to have a progress bar that shows that the native application is running.
The only ways would be to either create a callback in java (meaning the code in c++ would call the java function) to inform of the current progress or create a function that the java code calls to get the current progress of your task.
http://www.codeproject.com/Articles/22881/How-to-Call-Java-Functions-from-C-Using-JNI
The java code would then use the value to update the jprogress bar.
Another possible simpler solution from Adam's is to have your C++ program output an update of progress to standard output, perhaps a String representation of the percent of progress. The Java program's Process would then have its OutputStream monitored by calling getInputStream() on the Process (yeah, it's not a typo; it's getInputStream()) in a thread background to the Swing thread, and use the information for updating the JProgressBar.
As others have said you need to have a way for your java application to know how far alone your c++ application is.
If you want a quick fix, use a JProgressBar and set it to interdeminate. It will animate the bar to show you something is happening. Once your process returns set the bar to 100%.
Easy way:
ProcessBuilder processBuilder = new ProcessBuilder(command);
JProgressBar progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
Process p = processBuilder.start();
p.waitFor();
progressBar.setIndeterminate(false);
progressBar.setValue(progressBar.getMaxValue());
Better way:
ProcessBuilder processBuilder = new ProcessBuilder(command);
JProgressBar progressBar = new JProgressBar();
processBuilder.redirectErrorStream(true);
Process p = processBuilder.start();
InputStream is = p.getInputStream();
try {
in = new BufferedReader(new InputStreamReader(is, "UTF-8"));
while ((line = in.readLine()) != null) {
//error checking
int progressValue = Integer.parseInt(line);
progressBar.setValue(progressValue);
} finally {
in.close();
}
}
progressBar.setValue(progressBar.getMaxValue());

launch an external installer app in Mac from Java

I´m creating a small app in Java that needs to be used in Mac and Windows from a CD.
The basic idea of this app is just to have a main menu (different for Mac and Windows) where you can select several options (install an app, view the content of the CD, view the help manual...etc) with a the logo of a company...etc.
The app to be installed is going to be different in Windows and Mac.
What I want to do is launch the external installer and once is installed, i want to launch the app.
The main problem that i have is that once I've launched the installer in a different process, the waitfor() return a valid exitvalue and continues.
I want to wait until this app is totally installed before i try to run it.
for Windows
Runtime.getRuntime().exec(" \"c:/.../ExternalAppforWin.exe\"");
for Mac
File instFolder = new File(System.getProperty("user.dir") + "ExternalAppforMac.pkg")
Process p = Runtime.getRuntime().exec(new String[] { "open", instFolder.toString() });
int exitVal = p.waitFor();
if (exitVal==0)
...
Could you help me?
Thanks.
It seems that you need to check for the presence of the install window on the system rather than the executable. As far as I know, there is no system independent way to do this in Java, however with the use of powerful libraries like sun's JNA(which is supported on both windows and mac and can be found here) you can do this through the appropriate OS API calls.
here is an example of what you may want to do on windows, mac calls should be similiar:
import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WinDef;
.
.
.
//execute process
Process p = Runtime.getRuntime().exec(" \"c:/.../ExternalAppforWin.exe\"");
//wait for return value
int res = p.waitFor();
//if we have a valid return code begin waiting for window to be closed
if(res == 0)
{
//define a window handle variable
WinDef.HWND windowHandle = null;
do
{
//sleep a little while before polling the value
try{Thread.sleep(100);}catch(InterruptedException e){}
//try to fetch the window by title
windowHandle = User32.INSTANCE.FindWindow(null, "<Window Title>");
//if the handle is not null, the window is still open so sleep and then try try again
}while(windowHandle != null && windowHandle.getPointer() != Pointer.NULL);
//continue on with your code
}

Initiating a commandline tool from GUI

I want to fire a command line executible with the parameters entered in GUI.
Process class can be used to fork my required command line process from the Java application, and I used the getInputStream() method of Process object to get the result and got it displayed in the GUI.
private void confirmActionPerformed(java.awt.event.ActionEvent evt) {
String output;
try {
Process p = Runtime.getRuntime().exec("my command line exe with parameters");
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((output = stdInput.readLine()) != null) {
TextField.setText(TextField.getText()+output+"\n");
}
} catch (IOException e) {
System.out.println("Exception in Process");
e.printStackTrace();
}
}
This is my code which is an event listener of a button pressed event and I attempted to display the result of the process in the text field (java swing component).
This process actually runs for quite a long time and shows some statistics as and when it runs when run in command line, but when i attempt it in GUI with the above code I'm getting the entire consolidated result only after the process finish running. I'm not getting the TextField updated as and when it is executing.
What would be the cause of this issue?
This is because the whole thing is done by the Swing event-handling thread.
Perhaps should you consider creating a separate thread and update the TextField with a SwingUtilities.invokeLater().
As Maurice already pointed out, you shouldn't be doing intensive processing on the UI thread. The SwingWorker class helps with that. It's part of the standard API since 1.6. There is also a backport to 1.5 if you can't use 1.6.
This class makes it easier to put some processing task on another thread and display the result later so that your GUI doesn't block in the meantime. You can also use SwingUtilities.invokeLater() directly, of course, as suggested by Maurice, but for me SwingWorker is the way to go as it is quite easy and apparently the new standard way of doing this kind of thing.

Categories