Inno Setup需打包C#自包含发布版(dotnet publish -r win-x64 --self-contained true)并递归复制整个输出目录,同时设PrivilegesRequired=admin以支持管理员操作和注册表写入。

如何让 Inno Setup 正确识别并打包 C# 编译后的 .exe 和依赖 DLL
Inno Setup 本身不理解 .NET,它只做文件搬运工。你看到的“找不到入口点”或“运行一闪退”,大概率是没把 Microsoft.NETCore.App 运行时或 runtimeconfig.json 一起打包进去。
- 发布 C# 项目时,优先选
self-contained模式(dotnet publish -r win-x64 --self-contained true),这样所有依赖都打在输出目录里,Inno Setup 只需原样复制整个文件夹 - 若用
framework-dependent,必须确保目标机器已装对应版本的 .NET Desktop Runtime(比如 .NET 6.0+ Desktop Runtime),且你的.exe同级必须存在MyApp.runtimeconfig.json—— 缺这个文件,.NET 就不知道该加载哪个框架版本 - Inno Setup 的
[Files]段里别只写Source: "bin\Release\net8.0\MyApp.exe"; DestDir: "{app}",要加递归:Source: "bin\Release\net8.0\*"; DestDir: "{app}"; Flags: recursesubdirs
怎么处理 C# 程序需要管理员权限或注册表写入
默认情况下,Inno Setup 安装程序以当前用户权限运行,但 C# 应用若调用 Registry.LocalMachine 或写入 Program Files,会静默失败——不是报错,而是操作被重定向到虚拟化路径(如 VirtualStore)。
- 在
[Setup]段加上PrivilegesRequired=admin,否则安装器连HKEY_LOCAL_MACHINE都碰不到 - 如果 C# 程序自身需要提权运行(比如开机自启、服务安装),别在代码里硬调
Process.Start("cmd", "/c ..."),改用 Inno Setup 的[Run]段配合runascurrentuser或shellexec标志 - 注册表写入统一交给 Inno Setup:用
[Registry]段,比 C# 手动操作更可靠,也避免 UAC 弹窗时机错乱
为什么安装后双击 .exe 报错“无法加载 DLL”或“找不到指定模块”
这不是 .NET 错误,是 Windows 原生 DLL 加载失败,常见于用了 SQLite、FFmpeg、OpenCV 等带本地二进制依赖的 C# 库。
- 检查
bin\Release\net8.0\runtimes\win-x64\native\下有没有sqlite3.dll这类文件;Inno Setup 默认不递归进runtimes子目录,得显式加路径 - 用
Dependencies.exe(非 dumpbin)打开你的.exe,看它真正依赖哪些 DLL;缺失的往往不是你想到的那个,而是它的依赖链下游(比如vcruntime140.dll) - 别把
x86和x64混在一起:C# 项目设为AnyCPU+Prefer 32-bit时,实际跑的是 x86,那你就得打包runtimes\win-x86\native\下的 DLL,而不是 x64 版本
如何让 Inno Setup 自动检测并跳过已安装的 .NET 运行时
Inno Setup 没内置 .NET 检测逻辑,Check: 函数只能查注册表或文件存在性,而 .NET 6+ 的运行时注册位置分散、键名不固定。
- 不要试图读
HKEY_LOCAL_MACHINE\SOFTWARE\dotnet\Setup\InstalledVersions\x64\sharedhost\Version—— 这个路径在 .NET 7/8 已废弃,新版全靠dotnet --list-runtimes输出,但 Inno Setup 不能直接执行带空格路径的命令行 - 更稳妥的做法:用
[Code]段调用ShellExec('open', ExpandConstant('{sys}\cmd.exe'), '/c dotnet --list-runtimes > {tmp}\runtimes.txt', '', SW_HIDE, ewWaitUntilTerminated, Result),再读取临时文件解析 - 但注意:普通用户权限下
dotnet命令可能不可用(PATH 未包含 SDK 目录),所以最终建议——干脆不检测,直接打包 self-contained 版本,省事又确定
真正麻烦的从来不是脚本怎么写,而是搞清 C# 发布模式、Windows DLL 加载规则、Inno Setup 权限模型这三者的交界处;漏掉任意一层,都会变成“看着配置全对,就是跑不起来”。


















