i have a batch file saved on my desktop and it serves the purpose of opening a calculator when executed.
i want this batch file to function quite in the same way using java. i wrote the following command in netbeans
package runbatch;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Runbatch {
public static void main(String[] args) {
try {
Runtime.getRuntime().exec("cmd /c hello.bat");
} catch (IOException ex) {
Logger.getLogger(Runbatch.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
although i get the build to be successful i am not getting the calculator opened up.
Try this:
Runtime.getRuntime().exec("cmd /c start calculator.bat");
Or you can execute your program without going through a batch file, like so:
Runtime.getRuntime().exec("cmd /c start java NameOfJavaFile");
Add "start" argument and complete path of batch file:
Runtime.getRuntime().exec("cmd /c start D:\sandbox\src\runbatch\hello.bat");
This works for me.
I prefer something like this:
String pathToExecutable = "C:/Program Files/calculator.exe";
try
{
final List<String> processBuilderCommand = new ArrayList<String>();
// Here you can add other commands too eg a bat or other exe
processBuilderCommand.add(pathToExecutable);
final ProcessBuilder processbuilder = new ProcessBuilder(processBuilderCommand);
// Here you be able to add some additional infos to the process, some variables
final Map<String, String> environment = processbuilder.environment();
environment.put("AUTOBATCHNOPROGRESS", "no");
processbuilder.inheritIO();
final Process start = processbuilder.start();
start.waitFor();
}
catch (IOException | InterruptedException e)
{
LOGGER.error(e.getLocalizedMessage(), e);
}
i think it's a little bit flexibel then the others because you can add several and more then one execuable und you be able to add variables.
ProcessBuilder is the safe and right way of doing this in java :
String[] command = new String[]{"cmd", "/c" ,"hello.bat"};
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(command);
processBuilder.start();
Related
I'm trying to run a python script whenever a button on my gui (swing) is pressed. However, the script never runs and I'm not sure how to fix this. I know the script works fine independently, it should be py not python because windows, and my file system ntfs.
So far I've been trying to use code that can be summarized as below:
myBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Process p = Runtime.getRuntime().exec("py myScript.py");
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
I don't think I can chmod ntfs stuff but I tried setting permissions via right clicking the python file and trying to mess with the security settings. Full control for the script to users does nothing.
The python script has the following permissions, my guess is my code isn't working because it does not have execute permissions.
-rw-r--r--
Use complete python executable path instead of "py". It executes the file with just read permissions.
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Sample {
public static void main(String[] args) throws Exception {
try {
Process p = Runtime.getRuntime().exec("C:/Windows/py myScript.py");
String cmdOutput = null;
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
// read the output from the command
while ((cmdOutput = stdInput.readLine()) != null) {
System.out.println(cmdOutput);
}
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
myScript.py
print("This line will be printed.")
Output:
C:\Users\Administrator\Documents\demo>javac Sample.java
C:\Users\Administrator\Documents\demo>java Sample
This line will be printed.
Currently i am logged in to my system as administrator and trying to start/stop the tomcat service from java code.when i execute my program i am getting a prompt saying "Enter the password for Administrator:" in the console.
my java program:
package Snomed.Snomed;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Utility {
public static void main (String args[] )
{
try{
Process p=Runtime.getRuntime().exec("runas /profile /user:Administrator \"cmd.exe /c startup.bat\"");
BufferedReader BR=new BufferedReader(new InputStreamReader(p.getInputStream()));
String l;
while((l=BR.readLine()) != null){
System.out.print(l);
}
}catch (Exception ex){
ex.printStackTrace();
}
}
}
I have read some where that this problem can be overcome by writing a batch script (bat file) for running with admin privileges.So how do i go about making my own batch file.can someone provide me the script or batch file??
I have a two programs:
first, that uses Console object to read and write data
second, that should run first with some dynamically calculated arguments
Second program code looks like this:
String[] arguments = {
"cmd", "/c",
"java", "-cp", classPath
lauchClass,
// Arguments for first program
}
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
When fist programs starts from second, System.console() is null and it fails with NPE.
So, question is: is there any way to run another process with System.console() available?
The answer is simple: If you run your launcher from an IDE like Eclipse or IntelliJ IDEA, probably it does not have System.console() set in the first place, thus there is nothing the subprocess can inherit from. Just try to write something to System.console() from the launcher, it will also fail with the same error. But if you start your launcher from an interactive console like Cmd.exe or Git Bash, both the launcher and the process started via ProcessBuilder can write to System.console(). Your launcher does not even need "cmd", "/c", it works with or without those parameters.
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
File workDir = new File(".");
System.console().printf("Hi, I am the launcher app!%n");
String[] arguments = new String[] {
// "cmd", "/c",
"java", "-cp", classPath,
launchClass
};
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
}
}
package de.scrum_master.stackoverflow;
public class MyApp {
public static void main(String[] args) {
System.console().printf("Hi, I am an externally started app!%n");
}
}
Console log when started from IntelliJ IDEA:
Exception in thread "main" java.lang.NullPointerException
at de.scrum_master.stackoverflow.Launcher.main(Launcher.java:11)
(...)
Console log when started from cmd.exe:
Hi, I am the launcher app!
Hi, I am an externally started app!
Feel free to ask any follow-up questions.
Update: If you do not mind that the external program runs in its own interactive console instead of in the IDE console, you can use the Windows command start for that purpose and then either cmd /c (windows is closed immediately after external program has ended) or cmd /k (window stays open for you to inspect the result):
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
String[] arguments = new String[] {
"cmd", "/c", "start",
"cmd", "/k", "java", "-cp", classPath, launchClass
};
ProcessBuilder pb = new ProcessBuilder(arguments);
Process process = pb.start();
process.waitFor();
}
}
But if then you want to read/write from/to that console, you are back at square #1. You asked why you cannot inherit System.console() to a subprocess. Well, that is because it is null due to the way Eclipse and IntelliJ launch Java programs from within the IDE (see [here] for background info). But as Magnus said, you still have System.{out|in} and can use them as follows:
package de.scrum_master.stackoverflow;
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class Launcher {
public static void main(String[] args) throws IOException, InterruptedException {
String classPath = "out/production/SO_ExternalProcessSystemConsole";
String launchClass = "de.scrum_master.stackoverflow.MyApp";
File workDir = new File(".");
System.out.println("Hi, I am the launcher app!");
String[] arguments = new String[] { "cmd", "/c", "java", "-cp", classPath, launchClass };
ProcessBuilder pb = new ProcessBuilder(arguments);
pb.environment().putAll(System.getenv());
pb.directory(workDir);
pb.inheritIO();
Process process = pb.start();
process.waitFor();
System.out.print("What is your favourite city? ");
Scanner scanner = new Scanner(System.in);
String city = scanner.nextLine();
System.out.println("I guess that " + city + " is a nice place.");
}
}
package de.scrum_master.stackoverflow;
import java.util.Scanner;
public class MyApp {
public static void main(String[] args) {
System.out.println("----------------------------------------");
System.out.println("Hi, I am an externally started app.");
System.out.print("Please enter your name: ");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
System.out.println("Hello " + name + "!");
System.out.println("----------------------------------------");
}
}
Hi, I am the launcher app!
----------------------------------------
Hi, I am an externally started app.
Please enter your name: Alexander
Hello Alexander!
----------------------------------------
What is your favourite city? Berlin
I guess that Berlin is a nice place.
I want to use cmd Commands in java program,
Want to crope all images in folder, I downlaoded ImageMagick, and using cmd commands Its working 1 image,
cd C:\Users\Robert\Java-workspace\Crop_test\Crop_test1
cd convert -crop 312x312+0-10 image1.jpg new_image1.jpg
But, I want to use this in Java so, I can crop all images in folder by program, Here is my java program:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.omg.CORBA.portable.OutputStream;
public class test1 {
public static void main(String argv[]) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "C:\\Users\\Robert\\Java-workspace\\Crop_test\\Crop_test1\\", "convert -crop 312x312+0-10 image1.jpg new_image1.jpg");
Process p = pb.start();
p.waitFor();
}
}
Although you are asking how to use CMD and this was addressed on other answers I think that the best solution (considering your explanation of your implementation) would be to use a ImageMagick wrapper for Java as you can see here.
Cheers
You can invoke CMD commands as follows in Java;
Runtime.getRuntime().exec(your_command);
Best thing for you to do is to creat a batch file with the commands you need to run and then invoke your batch file using the following command;
Runtime.getRuntime().exec("cmd /C start D:\\test.bat");
because you cannot do any change directory commands using the Runtime class. Please try this option and let me know if you face any other issues.
A couple of things to try (both of which are untested):
Put a cd in the command line and use && to run both commands in one line.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.omg.CORBA.portable.OutputStream;
public class test1 {
public static void main(String argv[]) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "cd C:\\Users\\Robert\\Java-workspace\\Crop_test\\Crop_test1\\ && convert -crop 312x312+0-10 image1.jpg new_image1.jpg");
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
}
}
Change the directory that the ProcessBuilder starts in:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.omg.CORBA.portable.OutputStream;
public class test1 {
public static void main(String argv[]) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("cmd", "/c", "convert -crop 312x312+0-10 image1.jpg new_image1.jpg");
pb.directory(new File("C:\\Users\\Robert\\Java-workspace\\Crop_test\\Crop_test1\\"));
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
}
}
Incidentally, are you sure you want to import org.omg.CORBA.portable.OutputStream? Did you mean java.io.OutputStream instead?
EDIT: if things still aren't working, then the next step is to see whether the problem is that convert isn't being found. Let's just run convert on its own without any arguments and see if it spits out its usage message to standard output. Run the following:
public class test1 {
public static void main(String argv[]) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "convert");
pb.redirectErrorStream(true);
Process p = pb.start();
StreamGobbler g = new StreamGobbler(p.getInputStream(), "OUT");
g.start();
p.waitFor();
}
}
Use the StreamGobbler class here. Does this print out convert's usage method, with each line prefixed with OUT>?
I am running java 7 applications on unix machines. Is there a way to get the current umask value in pure java ?
In C I would use a combination of umask system calls, but I don't think I can call that in Java without resorting to JNI. Is there another approach ?
Edit: Here is a C example (from GUN libc docs):
mode_t
read_umask (void)
{
mode_t mask = umask (0);
umask (mask);
return mask;
}
A simple solution, if there is no Class/Method to get the umask, why don't you get it before call java and pass as a property?
Can you clarify? Do you want to read the umask of the application(the current java process)? Or do you want to read the umask value of some files on the file system?
You can use NIO (the used code is from the javadocs) to get some file attributes, or you can execute a shell command, since the process created with Runtime.execute inherits the umask of it's creator process.
So you should be able to solve your problem without the use of JNI.
package test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
public class Test {
private static final String COMMAND = "/bin/bash -c umask -S";
public static String getUmask() {
final Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(COMMAND);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String umask = reader.readLine();
if (process.waitFor() == 0)
return umask;
} catch (final IOException e) {
e.printStackTrace();
} catch (final InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();
}
return "";
}
public static void main(String[] args) throws IOException {
/*
* NIO
*/
PosixFileAttributes attrs = Files.getFileAttributeView(Paths.get("testFile"), PosixFileAttributeView.class)
.readAttributes();
System.out.format("%s %s%n", attrs.owner().getName(), PosixFilePermissions.toString(attrs.permissions()));
/*
* execute shell command to get umask of current process
*/
System.out.println(getUmask());
}
}