.NET Hosting Bundle修复时WPF安装程序崩溃问题求助
我开发了一款WPF(C#)安装程序用于Windows应用部署,流程包含以下步骤:
- 安装.NET Hosting Bundle 7.0.5
- 安装IIS
- 将应用文件复制到
C:/inetpub/MyApp - 为该文件夹授予
IIS_IUSRS和DefaultAppPool权限 - 创建IIS网站
localhost:8888 - 修复.NET Hosting Bundle(此步骤为必要操作,跳过会触发HTTP Error 500.19 - Internal Server Error)
- 重启IIS
当系统未预装.NET Hosting Bundle时,整个流程运行正常;但如果系统已预装同版本7.0.5,通过C#代码执行修复时,安装程序会直接崩溃且无法捕获错误。崩溃后手动打开安装包执行修复或通过CMD执行修复,IIS网站即可正常运行。
IIS安装代码
string file = @"dism.exe"; string arguments = $"/quiet /norestart /Online /Enable-Feature /FeatureName:IIS-WebServerRole /All"; Process process = new Process(); process.StartInfo.FileName = file; process.StartInfo.Arguments = arguments; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.Start(); process.WaitForExit();
已尝试的解决方法
- 以管理员身份运行程序
- 修复前停止IIS,修复后重启
- 通过
Process()执行修复 - 在WPF应用内通过CMD执行修复
- 上述方法的多种组合尝试
修复相关代码
最初的修复代码(未预装Hosting Bundle时可正常运行):
string file = @"./Source/dotnet-hosting-7.0.5-win.exe"; string arguments = $"/repair /quiet /norestart"; Process process = new Process(); process.StartInfo.FileName = file; process.StartInfo.Arguments = arguments; process.StartInfo.UseShellExecute = false; process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; process.Start(); process.WaitForExit();
添加超时逻辑的尝试:
int timeoutMilliseconds = 10000; if (!process.WaitForExit(timeoutMilliseconds)) { // 超时处理逻辑 }
另外还尝试过使用安装包的完整路径(未预装时有效),以及添加输出/错误数据接收事件,但均未解决问题。
修复前出现的错误:HTTP Error 500.19 - Internal Server Error(配置文件相关的内部服务器错误)
解决方案
先检测.NET Hosting Bundle是否已安装
不要直接执行修复,先通过注册表或dotnet --info检测目标版本是否已安装。例如读取注册表路径HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall下的相关条目,判断7.0.5版本的Hosting Bundle是否存在,仅在需要时执行修复。调整Process执行参数
执行系统级修复操作时,设置UseShellExecute = true并指定Verb = "runas"强制以管理员权限启动,解决隐性权限或进程启动问题:string file = @"./Source/dotnet-hosting-7.0.5-win.exe"; string arguments = "/repair /quiet /norestart"; Process process = new Process(); process.StartInfo.FileName = file; process.StartInfo.Arguments = arguments; process.StartInfo.UseShellExecute = true; process.StartInfo.Verb = "runas"; process.StartInfo.CreateNoWindow = true; process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; try { process.Start(); process.WaitForExit(); if (process.ExitCode != 0) { // 处理修复失败逻辑 } } catch (Exception ex) { // 捕获并记录异常 }使用MSIExec执行修复
提取Hosting Bundle的MSI包,通过msiexec.exe执行修复,稳定性更强:string file = "msiexec.exe"; string arguments = "/fa ./Source/dotnet-hosting-7.0.5-win.msi /quiet /norestart"; Process process = new Process(); process.StartInfo.FileName = file; process.StartInfo.Arguments = arguments; process.StartInfo.UseShellExecute = true; process.StartInfo.Verb = "runas"; process.StartInfo.CreateNoWindow = true; process.Start(); process.WaitForExit();完整捕获进程输出流
正确配置输出/错误流重定向,捕获崩溃时的详细日志:process.StartInfo.RedirectStandardOutput = true; process.StartInfo.RedirectStandardError = true; process.OutputDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Log(e.Data); }; process.ErrorDataReceived += (sender, e) => { if (!string.IsNullOrEmpty(e.Data)) Log(e.Data); }; process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit();修复后延迟重启IIS
修复完成后等待3-5秒,确保系统配置完全更新后再重启IIS:// 修复完成后 System.Threading.Thread.Sleep(3000); Process.Start("iisreset.exe", "/restart /noforce").WaitForExit();
内容的提问来源于stack exchange,提问作者edis1409

