我想以编程方式构建我的 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;
}
}
执行上述方法时,我面临两个问题:
- 在以下方法运行时,它不会在 dist 文件夹下生成 index.html 文件。注意:如果我直接在 cmd.exe 上运行“npm run build”命令,它会生成 index.html。
- 它不会长时间退出进程,我必须杀死它。
我错过了什么,我该如何解决?
注意:在运行上述方法之前,我已经运行了“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;
}
}