【问题标题】:Start multiple exe with arguments使用参数启动多个 exe
【发布时间】:2019-10-25 21:52:07
【问题描述】:

我有大约 5000 个文件夹,每个文件夹都包含一个 dos 可执行文件和所需文件。 目前我正在使用 for 循环来调用下面的代码。由于每次执行大约需要 5 秒,因此需要很长时间才能执行。 有没有可以同时执行所有exe文件的选项?

有什么想法吗?

谢谢

我尝试过使用

   start "" 1/ddd.exe input.dat 
   start "" 2/ddd.exe input.dat 
   start "" 3/ddd.exe input.dat 
   .
   .
   .

在批处理文件中。 input.dat 具有传递给 exe 的参数。但是exe打开了一个新窗口并且它不接受参数。第一个参数是 "2" 运行到 exe 的某些部分,第二个参数是任何数字以在程序完成后退出程序。

【问题讨论】:

  • 你几乎不可能有足够的内存来同时执行 5000 个程序,而且 CPU 负载和磁盘 I/O 的增加会使性能变得如此糟糕以至于无法接受。你真的在运行已经死了几十年的DOS吗? DOS 应用程序通常以 MB 为单位测量 RAM,而不是 GB。
  • 您可以创建 10 个批处理文件,每个批处理文件 500 个。
  • 我注意到您似乎也将一个名为 input.dat 的文件传递给每个文件。由于您没有更改或设置当前目录,因此您似乎还期望 5000 个可执行文件都可以使用同一个文件。您确定是否可以接受同一个文件 5000 次?
  • related 避免内存和 CPU 过载。
  • 可执行文件非常小,但需要两个输入参数。 input.dat 就是为此。它需要第一个参数“2”,因此它启动程序的特定部分以及之后退出程序的任何数字。 10 个批处理文件每个执行 500 个听起来也是个好主意。我只是不喜欢现在的 5~6 小时运行时间。

标签: windows batch-file cmd


【解决方案1】:

你试过了

for /D %%a in (*) do ( 
  echo processing: %%a 
  start /B "Name" cmd.exe "cd %%a & ddy.exe < parameters.txt"
)

我更喜欢start /D "%%a" /min "Name" cmd.exe /c "ddy.exe &lt; parameters.txt"/B 导致他们使用同一个控制台,并且他们可能会互相阻止。 /D 设置工作文件夹(不需要cd),/min 最小化窗口以保持屏幕清洁。
并且不要忘记 /c 使用 cmd 命令(没有,你不会得到并行进程)。

整体而言:

for /D %%a in (*) do ( 
  echo processing: %%a 
  start /D "%%a" /min "Name" cmd.exe /c "ddy.exe < parameters.txt"
)

【讨论】:

    【解决方案2】:

    这是一个非常简约的脚本,可以一次从列表中运行 N 个命令。如果您在受支持的 Windows 系统上,它将具有 PowerShell。

    没有错误检查或正确的帮助信息。它将标准输出写入指定的日志文件,但对命令的退出代码不做任何事情。如果出现故障,则需要从日志文件中进行识别。

    要使用它,请将以下代码放入文件Invoke-JobList.ps1

    使用您要运行的命令和每个命令的不同日志文件名创建一个 .csv 文件。多个命令的日志文件名不能相同。如果您有 5000 条命令要处理,您可能需要编写一个脚本/程序来生成它。

    我提供了一个示例 .csv 文件和一个用于测试的批处理文件。你不需要使用to.bat

    === 获取内容 .\Invoke-JobList.ps1

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory=$true)]
        [string[]]$jobFile
    
        ,[Parameter(Mandatory=$false)]
        [int]$nConcurrent = 2
    )
    
    $jobs = Import-Csv -Path $jobFile
    $jobHash = @{}
    $nJobsRunning = 0
    
    foreach ($job in $jobs) {
        if ($nJobsRunning -lt $nConcurrent) {
            Write-Verbose -Message "starting command $($job.command)"
            $j = Start-Job -ScriptBlock ([ScriptBlock]::Create($job.command))
            $jobHash[$j] = $job.logfile
            $nJobsRunning++
        }
    
        while ($nJobsRunning -ge $nConcurrent) {
            # wait for one or more jobs to state Completed
            $jobsRunning = Get-Job
            foreach ($jobRun in $jobsRunning) {
                if (($null -ne $jobHash[$jobRun]) -and ($jobRun.State -eq 'Completed')) {
                    Receive-Job -Job $jobRun | Out-File -FilePath $jobHash[$jobRun]
                    Remove-Job -Job $jobRun
                    $jobHash.Remove($jobRun)
                    $nJobsRunning--
                }
            }
        }
    }
    
    Write-Verbose -Message $($nJobsRunning.ToString() + " remaining jobs")
    
    # Wait for all remaining jobs to complete
    while ($nJobsRunning -gt 0) {
        $jobsRunning = Get-Job
        foreach ($jobRun in $jobsRunning) {
            if (($null -ne $jobHash[$jobRun]) -and ($jobRun.State -eq 'Completed')) {
                Receive-Job -Job $jobRun | Out-File -FilePath $jobHash[$jobRun]
                Remove-Job -Job $jobRun
                $jobHash.Remove($jobRun)
                $nJobsRunning--
            }
        }
    }
    

    === 获取内容 .\joblist3.csv

    command,logfile
    C:\src\jobs\to.bat 10,ss-001.txt
    C:\src\jobs\to.bat 10,ss-002.txt
    C:\src\jobs\to.bat 10,ss-003.txt
    C:\src\jobs\to.bat 10,ss-004.txt
    C:\src\jobs\to.bat 10,ss-005.txt
    C:\src\jobs\to.bat 10,ss-006.txt
    C:\src\jobs\to.bat 10,ss-007.txt
    

    === 获取内容 .\to.bat

    @ECHO OFF
    SET "TO=%1"
    IF "%TO%" == "" (SET "TO=5")
    REM Cannot use TIMEOUT command
    ping -n %TO% localhost
    EXIT /B 0
    

    使用参数调用它。

    .\Invoke-JobList.ps1 -jobFile joblist3.csv -nConcurrent 3 -Verbose
    

    【讨论】:

    • 感谢您的回答。对不起,我是新手。这对我来说看起来很复杂:D
    • @ash - 很抱歉,这似乎令人困惑。保存Invoke-JobList.ps1 文件。我在答案中添加了一些使用说明。这有帮助吗?
    • 谢谢点亮。我想我可以用for /D %%a in (*) do ( echo processing: %%a start /B "Name" cmd.exe "cd %%a &amp; ddy.exe &lt; parameters.txt" ) 运行它。我不确定这是否会更快。
    • @ash - 你将如何控制同时运行的数量?您的机器可以同时运行所有 5,000 个吗?
    • 点亮 - 我刚刚开始运行它。它使用 70% 的 CPU 和 20% 的内存。
    猜你喜欢
    • 2022-07-23
    • 2019-01-27
    • 2019-05-29
    • 2018-08-23
    • 2018-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多