Java Process类Runtime.getRuntime().exec() 执行bat脚本程序

简介: Java Process类Runtime.getRuntime().exec() 执行bat脚本程序

一、问题

Ruoyi架构,bat文件上传到了服务器的文件夹upload下,如何通过在前端点击“执行”,后端Java去操控对应的bat文件执行呢?

Java可以通过Process类的Runtime.getRuntime().exec调用外部的脚本或者是操作系统命令

二、工具介绍

Runtime.getRuntime().exec() 方法,用于调用外部可执行程序或系统命令,并重定向外部程序的标准输入、标准输出和标准错误到缓冲池。相当于在当前目录打开CMD窗口,

Runtime.getRuntime() 返回当前应用程序的Runtime对象,该对象的 exec() 方法指示Java虚拟机创建一个子进程执行指定的可执行程序,并返回与该子进程对应的Process对象实例。

Process process = Runtime.getRuntime().exec( "notepad.exe ");
//用于等待子进程完成再往下执行。
process.waitfor();

Process方法

// 等待当前线程等待,直到进程终止。
int waitFor()
// 杀掉子进程,如果已终止该子进程,此方法立即返回。
// 如果没有终止该子进程,调用的线程将被阻塞,直到退出子进程,0 表示正常终止。
void destroy()
// 返回子进程的出口值,值 0 表示正常终止
int exitValue()
// 获取子进程的错误流
InputStream getErrorStream()
// 获取子进程的输入流
InputStream getInputStream()
// 获取子进程的输出流
OutputStream getOutputStream()

如果执行Runtime.getRuntime().exec("notepad.exe") 相当于以下效果:

cmd /c start 命令可以打开一个新的命令提示符窗口,并在其中执行指定的命令或程序,但打开新窗口的根路径在当前目录,可以在命令中使用 cd 命令来切换路径

参数 /c 表示,这个cmd一旦被调用,程序不用等待cmd后面的内容执行完毕,就返回到调用start的环境里,这样可以避免如果cmd后面的内容运行过长而导致程序处于等待而呈现假死的现象。


例如cmd /c start 测试脚本程序.bat相当于打开一个新窗口执行bat程序

/K 参数表示在命令执行完毕后不关闭窗口,cd 命令用于切换路径。可以将 C:\path\to\directory 替换为你想要设置的路径,然后在 cmd /c start 命令中使用该命令即可。

例如,以下命令可以打开一个新的命令提示符窗口,并将其根路径设置为 C:\path\to\directory:

cmd /c start cmd.exe /K "cd C:\path\to\directory"

三、解决方法

首先我们创建一个脚本测试程序

将其通过前端上传到服务器上

由于Ruoyi默认上传文件时,会以profile+年/月/日/标识符的方式放入对应文件夹,我们可以看到文件目录


由于Runtime.getRuntime().exec() 可以传入字符串或者字符串数组,执行字符串中的CMD命令,但前提是,我们需要找到文件目录和文件名

先设置common目录

            filePath = filePath.substring(filePath.indexOf("profile"));
            //处理filePath,将profile替换为RuoYiConfig.getProfile()
            filePath = filePath.replace("profile", RuoYiConfig.getProfile());
            //处理filePath,将/替换为\
            filePath = filePath.replace("/", "\\");
            //设置common为filePath目录最后一个\之前的部分
            String common = filePath.substring(0, filePath.lastIndexOf("\\"));
       //进入common目录后,执行filePath
            File file = new File(filePath);
            String cmd = "cmd /c start cmd.exe /K \"cd /d " + common + " && " + file.getAbsolutePath() + "\"";
            Process process = Runtime.getRuntime().exec(cmd);

这个命令会打开一个新的命令提示符窗口,然后进入common目录,也就是E:\ftpTest\upload\2023\07\27并执行运行文件命令。请注意,如果您的文件路径中包含空格或其他特殊字符,您可能需要使用引号将其括起来,例如:

String cmd = "cmd /c start cmd.exe /K \"cd /d " + common + " && " + file.getAbsolutePath() + "\"";
String cmd = "cmd /c start cmd.exe /K \"cd /d " + common + " && \"" + file.getAbsolutePath() + "\"\"";

在Java中,可以使用Process类来执行命令,并通过waitFor()方法等待命令执行完成。waitFor()方法返回一个整数值,表示命令的执行结果。通常情况下,waitFor()方法返回0表示命令执行成功,返回非0值表示命令执行失败。可以使用以下代码示例来实现该功能:

import java.io.IOException;
public class CommandExecutor {
    public static void main(String[] args) {
        try {
            Process process = Runtime.getRuntime().exec("cmd /c start cmd.exe");
            int exitCode = process.waitFor();
            if (exitCode == 0) {
                System.out.println("Command executed successfully.");
            } else {
                System.out.println("Command execution failed.");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上面的代码中,我们使用Runtime.getRuntime().exec()方法执行cmd /c start cmd.exe命令,并通过process.waitFor()方法等待命令执行完成。最后,我们根据waitFor()方法的返回值来判断命令是否执行成功。

之后,前端点击执行后,服务器端将运行对应的bat文件


目录
相关文章
|
6天前
|
存储 安全 Java
Java——String类详解
String 是 Java 中的一个类,用于表示字符串,属于引用数据类型。字符串可以通过多种方式定义,如直接赋值、创建对象、传入 char 或 byte 类型数组。直接赋值会将字符串存储在串池中,复用相同的字符串以节省内存。String 类提供了丰富的方法,如比较(equals() 和 compareTo())、查找(charAt() 和 indexOf())、转换(valueOf() 和 format())、拆分(split())和截取(substring())。此外,还介绍了 StringBuilder 和 StringJoiner 类,前者用于高效拼接字符串,后者用于按指定格式拼接字符串
11 1
Java——String类详解
|
2天前
|
安全 Java
Java StringBuffer 和 StringBuilder 类详解
在 Java 中,`StringBuffer` 和 `StringBuilder` 用于操作可变字符串,支持拼接、插入、删除等功能。两者的主要区别在于线程安全性和性能:`StringBuffer` 线程安全但较慢,适用于多线程环境;`StringBuilder` 非线程安全但更快,适合单线程环境。选择合适的类取决于具体的应用场景和性能需求。通常,在不需要线程安全的情况下,推荐使用 `StringBuilder` 以获得更好的性能。
|
2天前
|
Java 开发者
Java Character 类详解
Java中的`Character`类是`java.lang`包的一部分,用于将基本类型`char`封装为对象,并提供了丰富的静态方法来处理字符,如类型判断、大小写转换等。
|
2天前
|
Java 索引
Java String 类详解
Java 中的 `String` 类用于表示不可变的字符序列,是 Java 标准库 `java.lang` 包的一部分。字符串对象一旦创建,其内容不可更改,修改会生成新对象。
|
6天前
|
Java
Java Character 类详解
`Character` 类是 Java 中的一个封装类,位于 `java.lang` 包中,主要用于处理单个字符。它是一个最终类,提供了多种静态方法来检查和操作字符属性,如判断字符是否为字母、数字或空格,以及转换字符的大小写等。此外,`Character` 类还支持自动装箱和拆箱,简化了 `char` 和 `Character` 之间的转换。以下是一些示例代码,展示了如何使用 `Character` 类的方法来检查字符属性和执行字符转换。掌握 `Character` 类的用法有助于更高效地处理字符数据。
|
1月前
|
Java 开发者
奇迹时刻!探索 Java 多线程的奇幻之旅:Thread 类和 Runnable 接口的惊人对决
【8月更文挑战第13天】Java的多线程特性能显著提升程序性能与响应性。本文通过示例代码详细解析了两种核心实现方式:Thread类与Runnable接口。Thread类适用于简单场景,直接定义线程行为;Runnable接口则更适合复杂的项目结构,尤其在需要继承其他类时,能保持代码的清晰与模块化。理解两者差异有助于开发者在实际应用中做出合理选择,构建高效稳定的多线程程序。
45 7
|
1月前
|
Oracle 安全 Java
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
JDK8到JDK28版本升级的新特性问题之在Java 15及以后的版本中,密封类和密封接口是怎么工作的
|
1月前
|
安全 Java
【Java集合类面试三】、Map接口有哪些实现类?
这篇文章介绍了Java中Map接口的几种常用实现类:HashMap、LinkedHashMap、TreeMap和ConcurrentHashMap,以及它们适用的不同场景和线程安全性。
|
3月前
|
Java
Java中,有两种主要的方式来创建和管理线程:`Thread`类和`Runnable`接口。
【6月更文挑战第24天】Java创建线程有两种方式:`Thread`类和`Runnable`接口。`Thread`直接继承受限于单继承,适合简单情况;`Runnable`实现接口可多继承,利于资源共享和任务复用。推荐使用`Runnable`以提高灵活性。启动线程需调用`start()`,`Thread`直接启动,`Runnable`需通过`Thread`实例启动。根据项目需求选择适当方式。
47 2
|
2月前
|
Java 开发者