我找到了几个通过 Java 类运行 cmd 命令的代码片段,但我无法理解它。
这是打开cmd的代码
public void excCommand(String new_dir){
Runtime rt = Runtime.getRuntime();
try {
rt.exec(new String[]{"cmd.exe","/c","start"});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我找到了一些其他链接来添加其他命令,例如 cd http://www.coderanch.com/t/109753/Linux-UNIX/exec-command-cd-command-java
任何人都可以帮助我了解如何 cd 一个目录,例如:
cd C:\Program Files\Flowella
然后在该目录上运行其他命令?
从不同目录运行进程到 Java 程序工作目录的一种方法是更改目录,然后在同一命令行中运行进程。您可以通过让
cmd.exe
运行命令行(例如 cd some_directory && some_program
.)来做到这一点
以下示例更改为不同的目录并从那里运行
dir
。不可否认,我可以只dir
那个目录而不需要cd
它,但这只是一个例子:
import java.io.*;
public class CmdTest {
public static void main(String[] args) throws Exception {
ProcessBuilder builder = new ProcessBuilder(
"cmd.exe", "/c", "cd \"C:\\Program Files\\Microsoft SQL Server\" && dir");
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while (true) {
line = r.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}
另请注意,我正在使用
ProcessBuilder
来运行命令。除此之外,这允许我通过调用 redirectErrorStream(true)
将进程的标准错误重定向到它的标准输出。这样做让我只有一个流可供阅读。
这会在我的机器上提供以下输出:
C:\Users\Luke\StackOverflow>java CmdTest
Volume in drive C is Windows7
Volume Serial Number is D8F0-C934
Directory of C:\Program Files\Microsoft SQL Server
29/07/2011 11:03 <DIR> .
29/07/2011 11:03 <DIR> ..
21/01/2011 20:37 <DIR> 100
21/01/2011 20:35 <DIR> 80
21/01/2011 20:35 <DIR> 90
21/01/2011 20:39 <DIR> MSSQL10_50.SQLEXPRESS
0 File(s) 0 bytes
6 Dir(s) 209,496,424,448 bytes free
你可以试试这个:-
Process p = Runtime.getRuntime().exec(command);
如果你想执行像
cd
这样的动作,那么使用:
String[] command = {command_to_be_executed, arg1, arg2};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("directory_location"));
例子:
String[] command = {"ls", "-al"};
ProcessBuilder builder = new ProcessBuilder(command);
builder = builder.directory(new File("/ngs/app/abc"));
Process p = builder.start();
将命令和所有参数拆分为字符串数组的单独字符串很重要(否则
ProcessBuilder
API 将无法正确提供它们)。
这里有一个更完整的命令行执行实现。
executeCommand("ls");
输出:
12/27/2017 11:18:11:732: ls
12/27/2017 11:18:11:820: build.gradle
12/27/2017 11:18:11:820: gradle
12/27/2017 11:18:11:820: gradlew
12/27/2017 11:18:11:820: gradlew.bat
12/27/2017 11:18:11:820: out
12/27/2017 11:18:11:820: settings.gradle
12/27/2017 11:18:11:820: src
private void executeCommand(String command) {
try {
log(command);
Process process = Runtime.getRuntime().exec(command);
logOutput(process.getInputStream(), "");
logOutput(process.getErrorStream(), "Error: ");
process.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
}
private void logOutput(InputStream inputStream, String prefix) {
new Thread(() -> {
Scanner scanner = new Scanner(inputStream, "UTF-8");
while (scanner.hasNextLine()) {
synchronized (this) {
log(prefix + scanner.nextLine());
}
}
scanner.close();
}).start();
}
private static SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy hh:mm:ss:SSS");
private synchronized void log(String message) {
System.out.println(format.format(new Date()) + ": " + message);
}
我的例子(来自真实项目)
文件夹——文件。
zipFile, filesString — 字符串;
final String command = "/bin/tar -xvf " + zipFile + " " + filesString;
logger.info("Start unzipping: {} into the folder {}", command, folder.getPath());
final Runtime r = Runtime.getRuntime();
final Process p = r.exec(command, null, folder);
final int returnCode = p.waitFor();
if (logger.isWarnEnabled()) {
final BufferedReader is = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = is.readLine()) != null) {
logger.warn(line);
}
final BufferedReader is2 = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((line = is2.readLine()) != null) {
logger.warn(line);
}
}
Runtime.getRuntime.exec()
.
例如,要获取 Windows 上默认浏览器的注册表值:
String command = "REG QUERY HKEY_CLASSES_ROOT\\http\\shell\\open\\command";
try
{
Process process = Runtime.getRuntime().exec(command);
} catch (IOException e)
{
e.printStackTrace();
}
然后如有必要,使用
Scanner
获取命令的输出。
Scanner kb = new Scanner(process.getInputStream());
注意:
\
是 String
中的转义字符,必须转义才能正常工作(因此是 \\
)。
但是,没有叫
cd
的可执行文件,因为它不能在单独的进程中实现。
ProcessBuilder
或Runtime.exec()
)。在这些情况下,您可以明确指定用于新启动进程的工作目录。
最简单的命令方式:
System.setProperty("user.dir", "C:\\Program Files\\Flowella");
试试这个:
Process runtime = Runtime.getRuntime().exec("cmd /c start notepad++.exe");
一旦你得到了对Process的引用,你就可以在它上面调用getOutpuStream来获取cmd提示符的标准输入。然后你可以像任何其他流一样使用 write 方法通过流发送任何命令。
请注意,它是 process.getOutputStream() 连接到生成进程上的标准输入。类似地,要获得任何命令的输出,您需要调用 getInputStream 然后将其作为任何其他输入流读取。
可以通过以下代码停止和禁用服务:
static void sdService() {
String[] cmd = {"cmd.exe", "/c", "net", "stop", "MSSQLSERVER"};
try {
Process process = new ProcessBuilder(cmd).start();
process.waitFor();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
line = null;
bufferedReader = null;
Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= disabled");
p.waitFor();
bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
可以通过以下代码启用和启动服务
static void esService() {
String[] cmd = {"cmd.exe", "/c", "net", "start", "MSSQLSERVER"};
try {
Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= auto");
//Process p = Runtime.getRuntime().exec("sc config MSSQLSERVER start= demand");
p.waitFor();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
line = null;
bufferedReader = null;
Process process = new ProcessBuilder(cmd).start();
process.waitFor();
bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
可以通过以下代码从任何文件夹执行命令。
static void runFromSpecificFolder() {
try {
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "cd \"C:\\Users\\himan\\Desktop\\Java_Test_Deployment\\jarfiles\" && dir");
//processBuilder.directory(new File("C://Users//himan//Desktop//Java_Test_Deployment//jarfiles"));
processBuilder.redirectErrorStream(true);
Process p = processBuilder.start();
p.waitFor();
String line = null;
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(p.getInputStream()));
while((line = bufferedReader.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String args[]) {
sdService();
runFromSpecificFolder();
esService();
}
你不能这样运行
cd
,因为cd
不是一个真正的程序;它是命令行的内置部分,它所做的只是更改命令行的环境。在子进程中运行它没有意义,因为那样你就改变了那个子进程的环境——但是那个子进程会立即关闭,丢弃它的环境。
要在您的实际 Java 程序中设置当前工作目录,您应该这样写:
System.setProperty("user.dir", "C:\\Program Files\\Flowella");
public class Demo {
public static void main(String args[]) throws IOException {
Process process = Runtime.getRuntime().exec("/Users/******/Library/Android/sdk/platform-tools/adb" + " shell dumpsys battery ");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
while (true) {
line = in.readLine();
if (line == null) { break; }
System.out.println(line);
}
}
}
从java执行cmd的方法之一!
public void executeCmd() {
String anyCommand="your command";
try {
Process process = Runtime.getRuntime().exec("cmd /c start cmd.exe /K " + anyCommand);
} catch (IOException e) {
e.printStackTrace();
}
}
这里的增值器是使用与号来批处理命令和使用 cd 更改驱动器的正确格式。
public class CmdCommander {
public static void main(String[] args) throws Exception {
//easyway to start native windows command prompt from Intellij
/*
Rules are:
1.baseStart must be dual start
2.first command must not have &.
3.subsequent commands must be prepended with &
4.drive change needs extra &
5.use quotes at start and end of command batch
*/
String startQuote = "\"";
String endQuote = "\"";
//String baseStart_not_taking_commands = " cmd /K start ";
String baseStart = " cmd /K start cmd /K ";//dual start is must
String first_command_chcp = " chcp 1251 ";
String dirList = " &dir ";//& in front of commands after first command means enter
//change drive....to yours
String changeDir = " &cd &I: ";//extra & makes changing drive happen
String javaLaunch = " &java ";//just another command
String javaClass = " Encodes ";//parameter for java needs no &
String javaCommand = javaLaunch + javaClass;
//build batch command
String totalCommand =
baseStart +
startQuote +
first_command_chcp +
//javaCommand +
changeDir +
dirList +
endQuote;
System.out.println(totalCommand);//prints into Intellij terminal
runCmd(totalCommand);
//Thread t = Thread.currentThread();
//t.sleep(3000);
System.out.println("loppu hep");//prints into Intellij terminal
}
public static void runCmd(String command) throws Exception {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
}
}
(正如其他人所说) 对于简单的命令,您可以这样做,例如:
Runtime.getRuntime().exec("cmd /c mkdir H:\\test\\BBB");
cmd /c
)
但是,对于一些复杂的命令,你可能需要做一个double
cmd.exe /c cmd.exe /c
,/c
或使用一些奇怪的/c
cmd
组合模式,cmd可能会冻结)),(((我怎么发现它?——我无法让它工作并尝试了多次;有一次不小心复制了cmd并运行它并找到了它。))
@例如::
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class T1 {
static String convertStreamToString(java.io.InputStream is) {
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
public static void main(String[] args) throws InterruptedException, IOException {
Process process;
System.out.println("---"); // creates a folder `BBB`
Runtime.getRuntime().exec("cmd /c mkdir H:\\test\\BBB");
// System.out.println("---");
// idk how to do `cd`
System.out.println("---"); // list file & folder in C:\
process = Runtime.getRuntime().exec("cmd.exe /c dir C:\\");
System.out.println(convertStreamToString(process.getInputStream()));
System.out.println("---"); // echo
process = Runtime.getRuntime().exec("cmd.exe /c echo \"Some Line\"");
System.out.println(convertStreamToString(process.getInputStream()));
// @atten: notice the double `cmd.exe /c cmd.exe /c `
// -- idk why must double - otherwise this wont execute
System.out.println("---"); // uses mysqldump to do something
process = Runtime.getRuntime().exec("cmd.exe /c cmd.exe /c \"C:\\Program Files\\MySQL\\MySQL Server 8.0\\bin\\mysqldump.exe\" -u root -pmysql db_drawandchat_01 > \"H:\\DrawAndChatApp_db\\DrawAndChat_20230503_0134_03326.sql\"");
}
// Output::
//
// ---
// ---
// Volume in drive C has no label.
// Volume Serial Number is 2C83-063F
//
// Directory of C:\
//
// 2019/06/29 11:56 <DIR> Intel
// 2022/04/18 06:07 <DIR> log
// 2019/12/07 17:14 <DIR> PerfLogs
// 2023/04/22 01:13 <DIR> Program Files
// 2023/04/08 21:27 <DIR> Program Files (x86)
// 2020/12/08 00:15 <DIR> Untitled
// 2021/04/23 04:57 <DIR> Users
// 2023/04/25 09:33 <DIR> Windows
// 0 File(s) 0 bytes
// 8 Dir(s) 3,268,296,704 bytes free
//
// ---
// "Some Line"
//
// ---
}