C#控制台调用多个批处理文件

5

你好,我有两个批处理文件:BatchA.batBatchB.bat
BatchA.bat调用了B1.batB2.batB3.bat三个批处理文件,并同时运行这三个批处理文件(三个批处理文件的运行顺序不重要)。以下是BatchA.bat的内容:

start B1.bat
start B2.bat
start B3.bat

BatchB.bat 调用了 B4.batB5.batB6.bat 三个批处理文件,并同时运行这三个文件(三个文件的运行顺序无关紧要)。 以下是 BatchB.bat 的内容:

start B4.bat
start B5.bat
start B6.bat

我是使用C#控制台应用程序调用 BatchA.bat BatchB.bat ,但我需要确保在启动 BatchB.bat 之前 BatchA.bat 已经完成。换句话说,我需要确保所有的 B1.bat B2.bat B3.bat 都完成后再启动 BatchB.bat
以下是C#代码:
proc.StartInfo.FileName = BatchA.bat;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
proc.WaitForExit();
int exitCode = proc.ExitCode;
proc.Close();
Console.WriteLine("Process Complete! exitCode: " + exitCode.ToString());

proc.StartInfo.FileName = BatchB.bat;
proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
proc.Start();
proc.WaitForExit();
exitCode = proc.ExitCode;
proc.Close();
Console.WriteLine("Process Complete! exitCode: " + exitCode.ToString());

当我运行这个程序时,所有6个批处理文件同时启动。我该如何确保只有在所有三个小批处理文件完成后,BatchA.bat 才会完成?


从BatchA调用BatchB。 - Squashman
5个回答

3

一个简单的方法是通过管道来连接“start”命令。当子进程结束时,左侧的管道将被关闭,从而关闭整个管道,批处理执行将继续。

因此,“batchA.cmd”可以编写为:

@echo off
    setlocal enableextensions disabledelayedexpansion

    echo starting BatchA
    (
        start "b1" cmd /c b1.cmd
        start "b2" cmd /c b2.cmd
        start "b3" cmd /c b3.cmd
    ) | more

    echo BatchA has ended

注意: 这种方法虽然简单,但可能会有缺陷(或者没有,这取决于需求)。由 b1...b3 启动的进程可能会保持管道活动状态。

@Squashman 已经发布了代码来处理不等待从内部批处理文件启动的进程。


那是一个聪明的做法。 - soja

1
这将同时在自己的窗口中启动所有三个批处理文件,并等待它们全部完成后再启动batchb。
 @echo off
 start "" /wait cmd /c batch1.bat |start "" /wait cmd /c batch2.bat |start "" /wait cmd /c batch3.bat
 batchb.bat

1
这并不确保 B1B2 已经结束。 - MC ND
1
@MCND,我更新了我的代码。不过没有你的那么简洁。 - Squashman
实际上,您发布了我要包含以处理我的答案中指出的行为的代码。以这种方式编写管道不会等待从 b1b3 启动的进程。 - MC ND

1
您可以使用 WAITFOR。在批处理 A 中,使用以下代码:

@echo off
waitfor done
waitfor done
waitfor done
echo done

然后在B1、B2、B3中,当批处理完成时使用WAITFOR /SI done

或者,您可以在B1、B2和B3中创建一个0字节的标记文件作为监视器,在结束Batch A之前检查其是否存在,但这可能更加复杂。


我不得不使用这个来使它工作。WAITFOR /S %computername% /SI done - Squashman
哦,我想知道它的区别在哪里。当在同一台计算机上运行时,我并不需要它。 - soja

0

我不认为批处理文件有办法做到这一点。 "start" 命令启动一个进程,并且不提供任何句柄来检查进程是否完成,或者等待它完成。

可以通过 PowerShell 命令来实现此操作。

PS > $x = Start-Process notepad -PassThru
PS > Wait-Process -Id $x.Id

0
尝试使用await和async。通过使用await关键字,您可以在BatchA完成之前继续其他工作。
例如,
  Task<int> getBatchAData = GetBatchDataAsync();

    if (batchAData != 0)
    {
       GetBatchB();
    }

   var yourData = await getBatchAData;

这里有额外的信息:https://msdn.microsoft.com/en-us/library/mt674882.aspx


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接