以编程方式 运行ning `npm 运行 build` 不会为 Angular 8 app 生成 `index.html`

Programmatically running `npm run build` does not generate `index.html` for Angular 8 app

我想以编程方式构建我的 Angular 8 应用程序以实现自动化过程并使用以下 C# 方法。


private bool RunBuildProd(string angularAppFolder)
{
            try
            {
                ProcessStartInfo objPI = new ProcessStartInfo(@"C:\Program Files\Nodejs\npm.cmd", $"run build");
                // ProcessStartInfo objPI = new ProcessStartInfo(@"cmd.exe", $"/c npm run build"); // Also tried this one
                objPI.WorkingDirectory = angularAppFolder;
                objPI.RedirectStandardError = true;
                objPI.RedirectStandardOutput = true;
                objPI.UseShellExecute = false;
                objPI.CreateNoWindow = true;
                objPI.WindowStyle = ProcessWindowStyle.Hidden;

                Process objProcess = Process.Start(objPI);
                string error = objProcess.StandardError.ReadToEnd();
                string output = objProcess.StandardOutput.ReadToEnd();

                objProcess.WaitForExit();
                return (objProcess.ExitCode == 0);
            }
            catch (Exception ex)
            {
                return false;
            }
}

执行上述方法时,我面临两个问题:

  1. 运行使用以下方法时,dist 文件夹下不会生成 index.html 文件。 注意:如果我直接在 cmd.exe 上 运行 "npm 运行 build" 命令,它会生成 index.html.
  2. 长时间不退出进程,我只好杀了它。

我错过了什么,我该如何解决?

注意:在运行使用上述方法之前,我已经运行“npm install”。

UPDATE:以下是基于 Serg 回答的更新代码,用于避免 stdout 和 stderr 的 read/write 死锁...


private bool RunBuildProd(string angularAppFolder)
{
    try
    {
        // ProcessStartInfo objPI = new ProcessStartInfo(@"cmd.exe", $"/c npm run build"); // Also tried this one
        ProcessStartInfo objPI = new ProcessStartInfo(@"C:\Program Files\Nodejs\npm.cmd", $"run build");
        objPI.WorkingDirectory = angularAppFolder;
        objPI.RedirectStandardError = true;
        objPI.RedirectStandardOutput = true;
        objPI.UseShellExecute = false;
        objPI.CreateNoWindow = true;
        objPI.WindowStyle = ProcessWindowStyle.Hidden;

        StringBuilder sbOutput = new StringBuilder();
        StringBuilder sbError = new StringBuilder();

        using (AutoResetEvent outputWaitHandle = new AutoResetEvent(false))
        using (AutoResetEvent errorWaitHandle = new AutoResetEvent(false))
        {
            Process objProcess = Process.Start(objPI);

            objProcess.OutputDataReceived += (sender, e) => {
                if (e.Data == null)
                {
                    outputWaitHandle.Set();
                }
                else
                {
                    sbOutput.AppendLine(e.Data);
                }
            };
            objProcess.ErrorDataReceived += (sender, e) =>
            {
                if (e.Data == null)
                {
                    errorWaitHandle.Set();
                }
                else
                {
                    sbError.AppendLine(e.Data);
                }
            };

            objProcess.BeginOutputReadLine();
            objProcess.BeginErrorReadLine();
            objProcess.WaitForExit();
            int timeout = 42000;
            if (outputWaitHandle.WaitOne(timeout) &&
                errorWaitHandle.WaitOne(timeout))
            {
                // Process completed. Check process.ExitCode here.
                return (objProcess.ExitCode == 0);
            }
            else
            {
                // Timed out.
                return (objProcess.ExitCode == 0);
            }
        }
    }
    catch (Exception ex)
    {
        return false;
    }
}

由于 stdout 和 stderr 的重定向,看起来像是死锁。可以在此处找到可能的解决方案