I'm working on a (non-malicious) screen-locking sort of Swing application, and I've adapted code from Martijn Courteaux's answer at Use Java to lock a screen to do this. The problem is that when I use Runtime.getRuntime().exec("explorer.exe"); to reopen the Explorer process at program closing, Netbeans thinks that my project is still running because the resulting explorer.exe is running. CMD prompt and JCreator don't have this issue.
Can anyone give an example of the preferred way to call a command like explorer.exe to avoid this happening with Netbeans?
Edit: I close the Explorer process at the start of the program (which includes the taskbar). When I run Explorer, it's not to open a Windows Explorer window (which works totally fine with the given answers) but to restore the regular Windows UI.
The problem is Runtime#exec is waiting for the child process to exit. This is the default behavior.
If you want to execute a parentless process (a process in which the parent process can terminate even though the child is still running), you need to get a little more creative.
We use...
"cmd /C start /B /NORMAL " + yourCommand
I would highlight recommend using ProcessBuilder as it makes it significantly easier to build and execute external commands.
Something like...
ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "start", "/B", "/NORMAL", "explorer.exe");
pb.start();
For example....
nb I run this is NetBeans and the program exited after/as explorer opened.
There is one little draw back. This doesn't like long file names. You'll need to find some way to produce short file names/paths for this to work. I was forced to use JNI solution for this
ProcessBuilder allows you to create and control processes.
Here's some example code, it's fairly complex but I don't have time to dumb it down (no offense): https://github.com/Xabster/Botster/blob/master/src/commands/ExecCommand.java
Related
My team is currently working on a project in Java that involves the robot simulation software Gazebo. To launch Gazebo with a specific world, we have written a shell script that we want to execute with the Runtime.getRuntime().exec(...) command in Java (or ProcessBuilder).
Here is our problem:
If we start that script from the terminal, everything works perfectly i.e. you can see a world with one of our models (pylons):
However, if we try to execute that script from within our Java application, it just shows this (models are recognized but not visualized):
We assume that Gazebo doesn't find the gazebo model path although they are defined in ~/.bashrc.
Has anyone an idea why it is not working. We know that most of you may not know Gazebo, but maybe some of you have dealt with similar issues.
Thanks in advance!
I found a solution that works for us:
Instead of the "Runtime.getRuntime().exec(...)" command, I use the ProcessBuilder.
ProcessBuilder builder = new ProcessBuilder();
builder.command(your_command);
builder.directory(new File(your_path));
Map<String, String> env = builder.environment();
env.put("GAZEBO_MODEL_PATH", variable_content);
Process process = builder.start();
Now, we can set GAZEBO_MODEL_PATH here and Gazebo loads all worlds correctly
I am trying to make a console-based Java application that starts some batch scripts that do some other irrelevant things. Presently, I just want to find the proof of concept
I have tried to use the following code:
Runtime.getRuntime().exec("cmd /c start pathtomybatch.bat");
This works fine until I turn it into a .jar file and attempt to execute it. Then it opens the batch file in a new command prompt window, which I don't want it to do. I want to open the batch file in the same window that my Java program is running in. I read about the start command on TechNet and SS64 and found out that apparently adding changing start to start /b would open the program in the same command prompt window. However, when I try to run this:
Runtime.getRuntime().exec("cmd /c start /b pathtomybatch.bat");
NetBeans says BUILD SUCCESSFUL for both lines of code, but when I try the second line of code, no command prompt window opens and my batch file doesn't get started.
I want to know how I can make Java open that batch file within the same command prompt window without stopping the Java application or waiting for it to finish.
Also, as a tiny extra request, could someone tell me if I could do the same for an .exe file?
I'm on Windows 7, but I want this app to work for people using Vista or newer.
The extra window is coming from the start command you initiate. See https://www.windows-commandline.com/cmd-start-command/
A better pattern is to use
Process p = Runtime.getRuntime().exec("cmd /c pathtomybatch.bat");
Then make sure you loop until p.exitValue() no longer throws an exception (which means the process has exited), and while looping copy all available bytes from p.getOutputStream() and p.getErrorStream() to System.out and/or System.err.
I have a Java application and i would like to spawn a new process(start a .bat file), that will essintially do the same thing as by double-clicking on it.
I have tried both Runtime.getRuntime().exec() and ProcessBuilder in order to spawn that process. Both those approaches work (they can start the .bat file), but my problem is that they do not actually do the exact same thing as by double clicking on it.
More specifically, this .bat file starts up a JVM (java.exe MyMainClass) which is configured to run using Windows SxS (side by side). Thus, i have created appropriate java.exe.config and java.exe.manifest files. When i doulbe click on that, the java application starts and the appropriate .dlls are loaded succesfuly (reason i need SxS).
My problem is that when i start the exact same .bat file (with the exact same arguments and process environment), either by using ProcessBuilder or Runtime.getRuntime().exec(), it doesn't seem to take into consideration my SxS configuration, thus the .dlls that i need are not loaded at all, resulting in errors.
Does anyone have any clue how to launch this .bat file the same way as windows laucnhes it when i am double clicking on it?
Additionally, does anyone have any experience with Java SxS deployment? I cannot really understand why ProcessBuilder ignores my SxS configuration.
Thanks in advance.
You can try starting a cmd window, which loads your application bat file:
Runtime.getRuntime().exec("cmd /c start cmd.exe /K \"C:\\path\\to\\the\\app.bat arg1 arg2\"");
I am trying to write a simple application that takes in a command line arguement (which will be a Powershell ps1 file) and then run it. So I have experemented with a number of different approaches and seem to be running into a problem. If I attempt to invoke powershell from within java, the windows process is started and is visible via process explorer, however powershell never returns, it hangs in some sort of loop by the looks of it. The command I am using is:
String command = "powershell -noprofile -noninteractive \"&C:\\new\\tst.ps1\"";
The command is then executed using:
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
At the moment I am hard coding the location to the ps1 file as I was trying to rule this out as an issue. Using a process explorer I can see the hanging powershell process and the command that was passed to it was :
powershell -noprofile -noninteractive "&C:\new\tst.ps1"
which when copied into a cmd window, works to launch the tst.ps1 file. The file itself is incredibly simple in this example and I think I can rule it out being the cause of the freeze as I have tried to launch other ps1 files the same behaviour can be seen.
To further add to the confusion, if I use the java code posted above and pass in powershell commands instead of a file name then it successfully runs.
I've scoured the web and see lots of people experiencing the same issue but no one seems to have posted there solution, I hope its a simple oversight on my part and can be easily fixed.
Any hints/tips are appreciated :D
Alan
You have to close OutputStream in order for Powershell to exit.
Runtime systemRuntime = Runtime.getRuntime();
Process proc = systemRuntime.exec(command);
proc.getOutputStream().close();
Is your external program writing to the standard outputs (err and out)?
If yes, it can hang waiting for you to consume them from the java parent process.
You can get those as InputStreams by calling
Process.getInputStream()
and
Process.getErrorStream()
There's more details here:
Javadoc for Process
Each time I use Runtime.exec("cmd /c start....") I am opening a cmd window. I would like to create a more seamless application by closing each previous cmd window. How can I do this?
If anyone knows of a better way to run a series of commands in the same cmd window rather than opening new ones each time I execute a command, please let me know.
Don't use start, that opens another window
Replace:
Runtime.exec("cmd /c start....")
with:
Runtime.exec("cmd /c ....")
Why do you need cmd windows?
I'd run the command directly in Java and capture the output and display it in a local window (if it's needed at all).
Just make sure you consume all the output from the program or it might stall. Also remember to close the stdout, stderr, and stdin streams or some file handles might leak (well, that's true on some JDKs on some Unix OSes... Windows, who knows).
You cannot control the opened windows from Java. But I suggest two solutions for you:
First:
Runtime.exec("cmd /c start /MIN ...")
The /MIN parameter will prevent windows from appearing.
Second: put all the applications you must call inside the same batch file and call it once. :-)