This tutorial builds Windows apps: a portable zip (windows), an installer (exe, with Inno Setup) and an
.msix package (msix), with optional code signing. It builds on Windows only; the three targets share one
flutter build windows.
What you need#
- Visual Studio with the Desktop development with C++ workload.
-
For
exe: Inno Setup 6 (winget install --id JRSoftware.InnoSetup -e). fpack findsISCC.exein the default install folders, or atwindows.inno_setup.iscc. -
For
msix: themsixpackage as a dev dependency:dart pub add --dev msix. - For signing:
signtool(Windows SDK) and a code signing certificate. -
A project path with ASCII characters only.
flutter build windowsfails in paths with, for example, Chinese characters (Unable to read file … app.dill); doctor warns about it. Alternatively enable "Beta: Use Unicode UTF-8 for worldwide language support" in the Windows region settings.
1. Check the machine#
fpack doctor windows exe msix
2. Build the portable zip#
fpack build windows
The result is dist\1.0.0+1\my_app-1.0.0+1-windows-x64-portable.zip: the Release folder zipped. Users unzip it and run the
.exe.
3. Build the installer#
fpack build exe
fpack generates an Inno Setup script from your project metadata and compiles it to my_app-1.0.0+1-windows-x64-setup.exe.
fpack init generates windows.inno_setup.app_id once: keep it stable
so upgrades replace the installed version.
windows:
inno_setup:
languages: [en, zh-CN] # the first is the default; fpack ships the Chinese file older Inno versions lack
privileges: user # user (no admin) | admin | ask
desktop_icon: checked # checked | unchecked | none
license_file: LICENSE.txt
Inno Setup also supports publisher and URLs, copyright, install directory, Start menu group, info pages, setup icon, wizard images, minimum Windows version and compression (see the
reference). To use your own script, set windows.inno_setup.script. Company and product details come from
app.* (Names, versions and output).
4. Build the MSIX#
fpack build msix
fpack runs dart run msix:create with settings from windows.msix, which take precedence over
msix_config in pubspec.yaml:
windows:
msix:
publisher: "CN=Your Company"
capabilities: [internetClient]
protocol_activation: [myapp]
Display name, publisher display name, identity name, version, logo, languages, file extensions, execution alias, start at login, minimum OS version and Store mode are all available.
Note
The msix package reads the description only from pubspec.yaml (msix_config.description, else
description). When windows.msix.description or app.description
differ, fpack prints the entry to add.
5. Sign the code#
Code signing is optional but avoids SmartScreen warnings. Choose one certificate source in
windows.sign:
| Source | Keys | Variables |
|---|---|---|
a .pfx file |
certificate + password |
FPACK_WINDOWS_CERTIFICATE, FPACK_WINDOWS_CERTIFICATE_PASSWORD |
| the certificate store |
thumbprint
(
/sha1
) or
subject
(
/n
), with
store
(default
My
) and
machine_store: true
|
FPACK_WINDOWS_CERT_THUMBPRINT, FPACK_WINDOWS_CERT_SUBJECT |
| a signtool plugin (cloud signing, e.g. Azure Trusted Signing) | dlib + dlib_metadata |
FPACK_WINDOWS_SIGN_DLIB, FPACK_WINDOWS_SIGN_DLIB_METADATA |
windows:
sign:
certificate: ${WINDOWS_PFX} # or thumbprint: / subject: / dlib:
password: ${WINDOWS_PFX_PASSWORD}
url: https://example.com
Right after flutter build windows, fpack signs files of the Release folder (default
*.exe and *.dll), so the portable zip, the installer and the MSIX all contain signed binaries. The Inno Setup installer and uninstaller are signed through
SignTool=; the MSIX is signed by msix:create with the same certificate (with
dlib, fpack signs the finished MSIX). Every signature uses SHA-256 and an RFC 3161 timestamp (timestamp_url, default
http://timestamp.digicert.com), with description (/d) and url
(/du). Afterwards signtool verify /pa checks it; a failure (for example a self-signed test certificate) is only a warning, and
verify: false turns the check off.
signtool is found on PATH or in the newest Windows SDK, or set signtool. fpack doctor
reports it and how to install it: winget install Microsoft.WindowsSDK.10.0.26100 (needs admin; without admin rights, extract signtool from the
Microsoft.Windows.SDK.BuildTools NuGet package and set signtool).
Tip
Keep the certificate password in a variable (${WINDOWS_PFX_PASSWORD}) or CI secret. fpack never prints it.
Hooks and quoting#
Hooks run through cmd /S /C on Windows, so use %VAR%
for hook variables (%FPACK_OUTPUT_DIR%); quoted paths work as typed.
In CI#
Use windows-latest; see CI recipes.
If something goes wrong#
| Message | Fix |
|---|---|
Inno Setup (ISCC.exe) not found |
winget install --id JRSoftware.InnoSetup -e
, or set
windows.inno_setup.iscc
|
Unable to read file … app.dill | move the project to an ASCII-only path |
| msix target fails with a missing package | dart pub add --dev msix |
| signtool not found | install the Windows SDK or set windows.sign.signtool |
More on the troubleshooting page.
本教程构建 Windows 应用:便携 zip(windows)、安装程序(exe,使用 Inno Setup)和 .msix
包(msix),可选代码签名。只能在 Windows 上构建;三个目标共用一次 flutter build windows。
你需要什么#
- 装有 使用 C++ 的桌面开发 工作负载的 Visual Studio。
-
exe:Inno Setup 6(winget install --id JRSoftware.InnoSetup -e)。fpack 会在默认安装目录找ISCC.exe,也可用windows.inno_setup.iscc指定。 msix:把msix包作为开发依赖:dart pub add --dev msix。- 签名:
signtool(Windows SDK)和代码签名证书。 -
项目路径只能包含 ASCII 字符。
flutter build windows在带有中文等字符的路径下会失败(Unable to read file … app.dill),doctor 会提示。也可以在 Windows 区域设置里启用“Beta: 使用 Unicode UTF-8 提供全球语言支持”。
1. 检查机器#
fpack doctor windows exe msix
2. 构建便携 zip#
fpack build windows
结果是 dist\1.0.0+1\my_app-1.0.0+1-windows-x64-portable.zip:压缩后的 Release 目录。用户解压后运行 .exe
即可。
3. 构建安装程序#
fpack build exe
fpack 根据项目元数据生成 Inno Setup 脚本,编译成 my_app-1.0.0+1-windows-x64-setup.exe。fpack init
只生成一次 windows.inno_setup.app_id,请保持它不变,这样升级才会替换已安装的版本。
windows:
inno_setup:
languages: [en, zh-CN] # 第一个是默认语言;fpack 自带旧版 Inno 缺少的中文语言文件
privileges: user # user(无需管理员)| admin | ask
desktop_icon: checked # checked | unchecked | none
license_file: LICENSE.txt
Inno Setup 还支持发布者和网址、版权、安装目录、开始菜单组、信息页、安装图标、向导图片、最低 Windows 版本和压缩方式(见参考)。要用自己的脚本,设置
windows.inno_setup.script。公司和产品信息来自 app.*(名称、版本与输出)。
4. 构建 MSIX#
fpack build msix
fpack 用 windows.msix 的设置运行 dart run msix:create,这些设置优先于 pubspec.yaml
里的 msix_config:
windows:
msix:
publisher: "CN=Your Company"
capabilities: [internetClient]
protocol_activation: [myapp]
显示名称、发布者显示名称、标识名称、版本、徽标、语言、文件扩展名、执行别名、开机启动、最低系统版本和 Store 模式都可以设置。
说明
msix 包只从 pubspec.yaml 读取描述(msix_config.description,否则是 description)。当
windows.msix.description 或 app.description 与之不同时,fpack 会打印需要添加的条目。
5. 代码签名#
代码签名是可选的,但能避免 SmartScreen 警告。在 windows.sign 里选择一种证书来源:
| 来源 | 键 | 变量 |
|---|---|---|
.pfx 文件 |
certificate + password |
FPACK_WINDOWS_CERTIFICATE、FPACK_WINDOWS_CERTIFICATE_PASSWORD |
| 证书库 |
thumbprint
(
/sha1
)或
subject
(
/n
),配合
store
(默认
My
)和
machine_store: true
|
FPACK_WINDOWS_CERT_THUMBPRINT、FPACK_WINDOWS_CERT_SUBJECT |
| signtool 插件(云签名,如 Azure Trusted Signing) | dlib + dlib_metadata |
FPACK_WINDOWS_SIGN_DLIB、FPACK_WINDOWS_SIGN_DLIB_METADATA |
windows:
sign:
certificate: ${WINDOWS_PFX} # 或 thumbprint: / subject: / dlib:
password: ${WINDOWS_PFX_PASSWORD}
url: https://example.com
flutter build windows 一结束,fpack 就对 Release 目录里的 files(默认 *.exe
和 *.dll)签名,所以便携 zip、安装程序和 MSIX 里的二进制都是已签名的。Inno Setup 的安装程序和卸载程序通过 SignTool=
签名;MSIX 由 msix:create 用同一张证书签名(使用 dlib 时,fpack 对生成好的 MSIX 签名)。每个签名都使用 SHA-256 和 RFC 3161 时间戳(timestamp_url,默认
http://timestamp.digicert.com),并带上 description(/d)和 url(/du)。之后
signtool verify /pa 会检查签名;失败(例如自签名的测试证书)只是警告,verify: false 可以关闭检查。
signtool 从 PATH 或最新的 Windows SDK 中查找,也可以设置 signtool。fpack doctor
会报告它以及安装方法:winget install Microsoft.WindowsSDK.10.0.26100(需要管理员;没有管理员权限时,从 NuGet 包 Microsoft.Windows.SDK.BuildTools
里提取 signtool 并设置 signtool)。
提示
把证书密码放在变量(${WINDOWS_PFX_PASSWORD})或 CI 密钥里。fpack 绝不会打印它。
钩子与引号#
钩子在 Windows 上通过 cmd /S /C 运行,所以钩子变量要写成 %VAR%(%FPACK_OUTPUT_DIR%);带引号的路径照常使用。
在 CI 中#
使用 windows-latest;见 CI 示例。
出问题时#
| 提示 | 处理 |
|---|---|
Inno Setup (ISCC.exe) not found |
winget install --id JRSoftware.InnoSetup -e,或设置 windows.inno_setup.iscc |
Unable to read file … app.dill | 把项目移到只含 ASCII 的路径 |
| msix 目标提示缺少包 | dart pub add --dev msix |
| 找不到 signtool | 安装 Windows SDK 或设置 windows.sign.signtool |
更多见故障排查页。