524 字
3 分钟
用 C# 写的桌面软件,用户要先装 C# 吗?

不用。这是个常见误解,但里面有几个概念值得分清楚。

用户其实不需要装”C#”#

“C#“是语言,没法”装”。用户机器上可能需要的是 .NET Runtime——但是否需要、需要多大,取决于开发者选哪种部署方式。

类比:用 TypeScript 写 Electron 应用时,用户也不会被要求”装 TypeScript”或”装 Node.js”——因为 Electron 把 Chromium + Node.js 运行时直接打包进了 app。.NET 也有同样能力,只是开发者要主动选。

.NET 8 的四种部署方式#

方式用户要装 .NET 吗包体积启动适合
Framework-dependent (FDD)~5-10 MB一般内部工具,环境可控
FDD + Bootstrapper 自动装不需手动app 5-10MB + 首次下载 ~70MB一般联网装机场景
Self-Contained (SCD)完全不需要~60-80 MB一般离线分发、企业部署
Native AOT完全不需要~10-30 MB极快 (<100ms)服务进程、CLI、对启动敏感的组件

跟 Electron 体积对比#

Electron 现状: ~150 MB
FDD + bootstrapper: ~10 MB + 首次下载 70 MB
Self-Contained: ~60-80 MB
Native AOT: ~10-30 MB

任何一种都比 Electron 小。NativeAOT 是数量级优势。

NativeAOT 的限制#

不是免费午餐:

  • 没有运行时反射(很多老库依赖反射,会编译失败或运行时报错)
  • 没有动态加载程序集
  • 不支持 System.Reflection.Emit
  • 不能用 dotnet ef 这类依赖反射的工具运行时操作
  • 编译时间长(几分钟级别)

所以一般规则:纯业务进程、服务、CLI 适合 AOT;带复杂 UI 框架(如 WinUI 3、WPF)的进程用 Self-Contained 更稳

混合部署是常态#

一个桌面产品通常多个进程组合:

EasyRemote.Service ← Native AOT (小、快、安全审计加分)
EasyRemote.Helper ← Native AOT (桌面切换敏感,必须 <100ms 启动)
EasyRemote.App (WinUI3) ← Self-Contained (WinUI3 用反射,AOT 兼容性不完善)
libwebrtc.dll ← 静态库
─────────────────────────────────────
合计 ~115MB,完全离线可装,无任何"请先安装 X"对话框

给用户的体感#

双击 .msi → 装完 → 直接用。全程不联网、不弹运行时安装提示。和 Electron 一样甚至更好。

用 C# 写的桌面软件,用户要先装 C# 吗?
https://blog.cuixu.cn/posts/csharp-deployment-runtime-question/
作者
崔旭
发布于
2026-05-22
许可协议
CC BY-NC-SA 4.0