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

时间:2014-11-18 06:23:21

标签: java batch-file cmd

我目前正在修改我编写的一个小应用程序,作为我正在采取的安全课程的演示。教授喜欢它,并要求进行一些我无法弄清楚的修改。我想添加能够作为参数传递给批处理文件的代码中的一些变量(即要运行的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块中处理它们......

@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%
    )

1 个答案:

答案 0 :(得分:1)

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

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

示例set /A "noiter=text" yoursef的效果。现在我们可以测试noiter变量的值:

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

最后,将下一个代码段替换为rem loop here以上的代码段:

  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 commandsetlocalenabledelayedexpansion等等。