问题描述
我想以编程方式为自动化流程构建我的 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;
}
}