java - 从 Java 中的批处理文件运行多个 cmd.exe 进程

标签 java batch-file cmd

我目前正在修改一个小应用程序,该应用程序是我为正在学习的安全类(class)进行演示而编写的。教授很喜欢它,并要求进行一些我无法弄清楚的修改。我想添加将代码中的一些变量作为参数传递到批处理文件的功能(即要运行的 cmd.exe 实例的数量以及下面代码中的消息变量)。

使用 Launching multiple shell prompts from a single batch file 中找到的答案在其他有用的 SO 线程中,以下是我整理的代码示例:

批处理文件:

@echo off

if not "%1" == "" goto :%1

SET message="The random number is: "

SET /a rand=%RANDOM%

start "Job 1" "%~dpfx0" job1
start "Job 2" "%~dpfx0" job2
start "Job 3" "%~dpfx0" job3
goto :eof

:job1
call :showMessage %message% %rand%

:job2
call :showMessage %message% %rand%

:job3
call :showMessage %message% %rand%

:showMessage 
echo %~1 %~2

这对于生成 3 个 cmd.exe 实例非常有效。不过,我很困惑如何动态选择要运行的作业数量以及如何使用上述配置将变量传递到批处理文件。我想我需要一个 FOR 循环,但我不确定如何使用上述设置或全新的方式来完成它。

我 110% 确定批处理文件中的行“if not "%1"== ""goto :%1”是绝对必要的,因为如果没有它,系统将不断打开 cmd.exe 进程(实验结果在几次硬重置中)。它会干扰将参数传递到批处理文件,但我无法找到使用它的方法。

供引用:

批处理文件通过以下代码在 Java 中执行:

public class CmdProcess{
    Runtime rt;

    public cmdProcess() {
        rt = Runtime.getRuntime();
    }

    public void startSpawning() {
        try {
            rt.exec("cmd.exe /C example.bat");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

我使用以下监听器从 GUI 代码调用此类:

private void setupListeners() {
    class spawnButtonListener implements ActionListener {
        public void actionPerformed(ActionEvent ae) {
            // Fire off 3 cmd.exe processes that show a message
            CmdProcess proc = new CmdProcess ();
            proc.startSpawning();
            // Increment the local counter and display on the client
            processCounter += 3;
            processCounterTextField.setText(Integer.toString(processCounter));
            }
        }

tl;dr:我需要知道是否可以在使用 Java 执行的批处理文件中使用 DOS 魔法来传递运行任意数量的 cmd.exe 实例(每个实例将执行)所需的参数相同的命令。

编辑以包含解决方案: 根据 @JosefZ 的输入,这是一个按照我需要的方式工作的解决方案:

@echo off
if not %1 == "" (
    set /A noiter=%1
    ) Else (
    set /A noiter=1
    )

SET message="The random number is: "

SET /a rand=%RANDOM%

if %noiter% == 0 (
    call :showMessage %message% %rand%
    ) Else (
    For /L %%G IN (1, 1, %noiter%) do (
        start "Job %%G" "%~dpfx0" job%%G
        set /a rand=%RANDOM%
        :job%%G
        call :showMessage %message% %rand%
        )
    )
)

:showMessage
echo %~1 %~2

如果我想传递额外的参数,我会在第一个 if block 中处理它们......

@echo off
if not %1 == "" (
    rem passed in parameters
    set /A noiter=%1
    set /A message=%2
    set /A rand=%3
    ) Else (
    rem default parameters
    set /A noiter=1
    set message="The random number is: "
    set /a rand=%RANDOM%
    )

最佳答案

您知道我们可以使用参数调用脚本。让我们按如下方式检查此参数:如果它是数字值,则认为这是要启动的 cmd.exe 的实例数,并将其记住为数字环境变量:set/A "noiter= %1";否则它只是一个结束标志。代码如下:

if not "%1" == "" (
  set /A "noiter=%1"
) Else (
  set /A "noiter=1"
)

自己尝试一下set/A "noiter=text" 的效果。现在我们可以测试 noiter 变量的值:

if "%noiter%" == "0" (
  call :showMessage %message% %rand%
) Else (
  rem loop here
)

最后,用下一个代码片段代替上面的rem循环:

  rem loop from 1 stepping 1 to "noiter"
  For /L %%G IN (1, 1, %noiter%) do (
    rem for testing purposes only: echo our command line first  
    echo start "Job %%G" "%~dpnx0" job%%G
    rem for testing purposes only: simulate real call
    set /a "rand=%RANDOM%"
    call :showMessage %message% %rand%
  )

这只是一个原始蓝图;仍然存在一些问题:例如%random% 往往保持不变:-)

因此,请了解更多信息 set command , setlocal , enabledelayedexpansion等等等等

关于java - 从 Java 中的批处理文件运行多个 cmd.exe 进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26987929/

相关文章:

java - Mockito 测试类,在构造函数中创建依赖项

java - 在等待时既被通知又被中断的线程

java - 使用 Spring roo 在 GWT 中进行菜单导航

c - Windows 批处理/每行多个命令

windows - 从父批中杀死子批处理

Android:定位debug.keystore时命令行出现keytool错误

java - 在 Spring MVC Controller 中避免 NumberFormatException

PHP 和 IIS7--> 我更新了环境 %PATH% 但 PHP 的路径没有更新,即使在循环 IIS 之后也是如此

windows - 网络中断时打印到本地共享打印机

batch-file - 在cmd中关闭程序的计时器