1

我想以编程方式构建我的 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 run build”命令,它会生成 index.html。
  2. 它不会长时间退出进程,我必须杀死它。

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

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

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


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;
    }
}
4

1 回答 1

1

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

于 2021-06-11T19:54:17.983 回答