.NET 8.0 WinForms应用在目标服务器抛出文件未找到异常求助
.NET 8 WinForms WebView2 发布后在Windows Server 2022上抛出FileNotFoundException问题排查
我在VS2022中创建了一个包含最新WebView2 NuGet包的.NET 8.0 WinForms项目,开发机和本地发布目录中的.exe运行正常,但将整个发布目录复制到Windows Server 2022(64位AMD)服务器上后,运行.exe立即弹出未处理错误对话框,异常为System.IO.FileNotFoundException。服务器已安装.NET 8.0托管包和.NET 8.0 x64桌面运行时。
项目代码
myawesomeprogram.cs
namespace myawesomenamespace { internal static class myawesomeprogram { [STAThread] static void Main() { ApplicationConfiguration.Initialize(); Application.Run(new myawesomeform()); } } }
myawesomeform.designer.cs
namespace myawesomenamespace { partial class myawesomeform { private System.ComponentModel.IContainer components = null; protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } private void InitializeComponent() { myawesomewebview = new Microsoft.Web.WebView2.WinForms.WebView2(); ((System.ComponentModel.ISupportInitialize)myawesomewebview).BeginInit(); SuspendLayout(); myawesomewebview.AllowExternalDrop = true; myawesomewebview.CreationProperties = null; myawesomewebview.DefaultBackgroundColor = Color.White; myawesomewebview.Dock = DockStyle.Fill; myawesomewebview.Location = new Point(0, 0); myawesomewebview.Name = "myawesomewebview"; myawesomewebview.Size = new Size(800, 450); myawesomewebview.TabIndex = 4; myawesomewebview.ZoomFactor = 1D; AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(800, 450); Controls.Add(myawesomewebview); Name = "myawesomeform"; Text = "myawesomeform"; WindowState = FormWindowState.Maximized; Load += myawesomeform_Load; ((System.ComponentModel.ISupportInitialize)myawesomewebview).EndInit(); ResumeLayout(false); } private Microsoft.Web.WebView2.WinForms.WebView2 myawesomewebview; } }
myawesomeform.cs
using Microsoft.Web.WebView2.Core; namespace myawesomenamespace { public partial class myawesomeform : Form { private Random? myawesomerandom; public myawesomeform() { InitializeComponent(); } private async void myawesomeform_Load(object sender, EventArgs e) { CoreWebView2Environment? myawesomeenvironment = await CoreWebView2Environment.CreateAsync(); await myawesomewebview.EnsureCoreWebView2Async(myawesomeenvironment); myawesomerandom = new Random(); await Task.Delay(myawesomerandom.Next(1000, 2000)); myawesomewebview.Source = new Uri("http://lixxx.co.uk"); await Task.Delay(myawesomerandom.Next(1000, 2000)); myawesomewebview.Source = new Uri("http://lmfgtfy.co.uk"); } } }
发布配置文件
<?xml version="1.0" encoding="utf-8"?> <!-- https://go.microsoft.com/fwlink/?LinkID=208121. --> <Project> <PropertyGroup> <Configuration>Release</Configuration> <Platform>Any CPU</Platform> <PublishDir>C:\dev\_pub</PublishDir> <PublishProtocol>FileSystem</PublishProtocol> <_TargetId>Folder</_TargetId> <TargetFramework>net8.0-windows</TargetFramework> <RuntimeIdentifier>win-x64</RuntimeIdentifier> <SelfContained>false</SelfContained> <PublishSingleFile>true</PublishSingleFile> <PublishReadyToRun>true</PublishReadyToRun> </PropertyGroup> </Project>
异常信息
See the end of this message for details on invoking just-in-time (JIT) debugging instead of this dialog box. ************** Exception Text ************** System.IO.FileNotFoundException: The system cannot find the file specified. (0x80070002) ************** Loaded Assemblies ************** System.Private.CoreLib Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Private.CoreLib.dll ---------------------------------------- myawesomeproject Assembly Version: 1.0.0.0 Location: ---------------------------------------- System.Runtime Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Runtime.dll ---------------------------------------- System.Windows.Forms Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\8.0.7\System.Windows.Forms.dll ---------------------------------------- System.ComponentModel.Primitives Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.ComponentModel.Primitives.dll ---------------------------------------- System.Windows.Forms.Primitives Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\8.0.7\System.Windows.Forms.Primitives.dll ---------------------------------------- System.Drawing.Primitives Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Drawing.Primitives.dll ---------------------------------------- System.Collections.Specialized Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Collections.Specialized.dll ---------------------------------------- System.Runtime.InteropServices Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Runtime.InteropServices.dll ---------------------------------------- System.Threading Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Threading.dll ---------------------------------------- System.Diagnostics.TraceSource Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Diagnostics.TraceSource.dll ---------------------------------------- System.Collections Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Collections.dll ---------------------------------------- System.Drawing.Common Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\8.0.7\System.Drawing.Common.dll ---------------------------------------- Microsoft.Win32.Primitives Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\Microsoft.Win32.Primitives.dll ---------------------------------------- System.ComponentModel.EventBasedAsync Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.ComponentModel.EventBasedAsync.dll ---------------------------------------- System.Threading.Thread Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Threading.Thread.dll ---------------------------------------- Accessibility Assembly Version: 4.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\8.0.7\Accessibility.dll ---------------------------------------- Microsoft.Web.WebView2.WinForms Assembly Version: 1.0.2592.51 Location: ---------------------------------------- Microsoft.Web.WebView2.Core Assembly Version: 1.0.2592.51 Location: ---------------------------------------- mscorlib Assembly Version: 4.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\mscorlib.dll ---------------------------------------- System.ComponentModel.TypeConverter Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.ComponentModel.TypeConverter.dll ---------------------------------------- System.ComponentModel Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.ComponentModel.dll ---------------------------------------- System.Numerics.Vectors Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Numerics.Vectors.dll ---------------------------------------- System.Private.Uri Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Private.Uri.dll ---------------------------------------- Microsoft.Win32.SystemEvents Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App\8.0.7\Microsoft.Win32.SystemEvents.dll ---------------------------------------- System.Memory Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Memory.dll ---------------------------------------- System.Collections.NonGeneric Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Collections.NonGeneric.dll ---------------------------------------- System Assembly Version: 4.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.dll ---------------------------------------- System.Threading.ThreadPool Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Threading.ThreadPool.dll ---------------------------------------- System.Runtime.Loader Assembly Version: 8.0.0.0 Location: C:\Program Files\dotnet\shared\Microsoft.NETCore.App\8.0.7\System.Runtime.Loader.dll ---------------------------------------- ************** JIT Debugging **************
问题原因分析
这个异常的核心原因是WebView2 Runtime缺失,结合发布配置和环境情况,具体有两点:
- 服务器未安装WebView2 Runtime:Windows Server 2022默认不会预装WebView2 Runtime(桌面版Windows通常随Edge浏览器附带),而WebView2控件依赖该运行时的原生组件才能启动。开发机正常是因为已经安装了Edge或单独的WebView2 Runtime。
- 单文件发布未包含WebView2原生组件:启用了
<PublishSingleFile>true</PublishSingleFile>,但.NET单文件发布对非托管原生库的处理有限,WebView2的核心原生dll没有被正确打包到单文件中,也没有被复制到发布目录,导致服务器上运行时找不到这些依赖文件。从加载程序集列表可以看到Microsoft.Web.WebView2.WinForms和Microsoft.Web.WebView2.Core的Location为空,说明这些组件的依赖文件未被找到。
解决方法
方法一:在服务器上安装WebView2 Runtime
直接在Windows Server 2022上安装WebView2 Runtime,推荐使用Evergreen版本,它会自动安装最新版本并保持更新,适合长期维护的应用。
方法二:将WebView2 Runtime打包到发布目录
在项目中安装对应架构的WebView2 Runtime NuGet包,比如针对x64的Microsoft.Web.WebView2.Runtime.win-x64,这样发布时会将Runtime的原生文件复制到输出目录,无需服务器提前安装。安装后重新发布,将整个发布目录复制到服务器即可。
方法三:调整单文件发布配置
修改发布配置文件,添加<IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract>到PropertyGroup中,这样单文件运行时会自动提取原生库到临时目录使用。修改后的配置如下:
<PropertyGroup> <Configuration>Release</Configuration> <Platform>Any CPU</Platform> <PublishDir>C:\dev\_pub</PublishDir> <PublishProtocol>FileSystem</PublishProtocol> <_TargetId>Folder</_TargetId> <TargetFramework>net8.0-windows</TargetFramework> <RuntimeIdentifier>win-x64</RuntimeIdentifier> <SelfContained>false</SelfContained> <PublishSingleFile>true</PublishSingleFile> <PublishReadyToRun>true</PublishReadyToRun> <IncludeNativeLibrariesForSelfExtract>true</IncludeNativeLibrariesForSelfExtract> </PropertyGroup>
注意:这种方式需要确保服务器上的用户有临时目录的读写权限。
内容的提问来源于stack exchange,提问作者sanepete
相关产品推荐
相关产品推荐

