本页讨论了使用 Flutter 构建 Windows 应用的独特注意事项,包括 Shell 集成以及通过 Windows 上的 Microsoft Store 分发 Windows 应用。

与 Windows 集成

#

Windows 编程接口结合了传统的 Win32 API、COM 接口和更现代的 Windows 运行时库。由于所有这些都提供了基于 C 的 ABI,因此你可以使用 Dart 的外部函数接口库 (dart:ffi) 调用操作系统提供的服务。FFI 旨在使 Dart 程序能够高效地调用 C 库。它为 Flutter 应用提供了使用 malloccalloc 分配本机内存、支持指针、结构体和回调以及 longsize_t 等 ABI 类型的功能。

有关从 Flutter 调用 C 库的更多信息,请参阅使用 dart:ffi 进行 C 互操作

实际上,虽然以这种方式从 Dart 调用基本的 Win32 API 相对简单,但使用包装库来抽象 COM 编程模型的复杂性会更容易。win32提供了一个库,用于访问数千个常见的 Windows API,并使用 Microsoft 提供的元数据来确保一致性和正确性。该包还包括各种常见用例的示例,例如 WMI、磁盘管理、Shell 集成和系统对话框。

许多其他包都建立在此基础上,提供了惯用的 Dart 访问方式,例如Windows 注册表游戏手柄支持生物识别存储任务栏集成串口访问等。

更普遍地说,许多其他包支持 Windows,包括常见的包,如url_launchershared_preferencesfile_selectorpath_provider

支持 Windows UI 指南

#

虽然你可以使用任何你选择的视觉样式或主题,包括 Material,但有些应用开发者可能希望构建一个符合 Microsoft Fluent 设计系统约定的应用。fluent_ui作为 Flutter 精选,为现代 Windows 应用中常见的视觉效果和通用控件提供了支持,包括导航视图、内容对话框、浮出控件、日期选择器和树视图组件。

此外,Microsoft 提供了fluentui_system_icons,这是一个包,可轻松访问数千个 Fluent 图标,供你在 Flutter 应用中使用。

最后,bitsdojo_window支持“自绘”标题栏,允许你用与应用其余部分匹配的自定义标题栏替换标准 Windows 标题栏。

自定义 Windows 主机应用

#

当你创建一个 Windows 应用时,Flutter 会生成一个小型 C++ 应用程序来托管 Flutter。这个“运行器应用”负责创建和调整传统的 Win32 窗口大小、初始化 Flutter 引擎和任何本机插件,以及运行 Windows 消息循环(将相关消息传递给 Flutter 进行进一步处理)。

当然,你可以根据需要更改此代码,包括修改应用名称和图标,以及设置窗口的初始大小和位置。相关代码位于 main.cpp 中,你将找到类似如下的代码:

cpp
Win32Window::Point origin(10, 10);
Win32Window::Size size(1280, 720);
if (!window.CreateAndShow(L"myapp", origin, size))
{
    return EXIT_FAILURE;
}

myapp 替换为你希望在 Windows 标题栏中显示的标题,也可以选择调整大小和窗口坐标的尺寸。

要更改 Windows 应用程序图标,请将 windows\runner\resources 目录中的 app_icon.ico 文件替换为你喜欢的图标。

可以通过编辑 windows/CMakeLists.txt 文件中的 BINARY_NAME 变量来更改生成的 Windows 可执行文件名。

cmake
cmake_minimum_required(VERSION 3.14)
project(windows_desktop_app LANGUAGES CXX)

# The name of the executable created for the application.
# Change this to change the on-disk name of your application.
set(BINARY_NAME "YourNewApp")

cmake_policy(SET CMP0063 NEW)

当你运行 flutter build windows 时,在 build\windows\runner\Release 目录中生成的可执行文件将与新给定的名称匹配。

最后,应用可执行文件本身的其他属性可以在 windows\runner 目录中的 Runner.rc 文件中找到。在这里你可以更改嵌入在 Windows 应用中的版权信息和应用版本,这些信息显示在 Windows 资源管理器属性对话框中。要更改版本号,请编辑 VERSION_AS_NUMBERVERSION_AS_STRING 属性;其他信息可以在 StringFileInfo 块中编辑。

使用 Visual Studio 编译

#

对于大多数应用来说,允许 Flutter 使用 flutter runflutter build 命令处理编译过程就足够了。如果你正在对运行器应用进行重大更改,或者将 Flutter 集成到现有应用中,你可能希望直接在 Visual Studio 中加载或编译 Flutter 应用。

请按照以下步骤操作

  1. 运行 flutter build windows 创建 build\ 目录。

  2. 打开 Windows 运行器的 Visual Studio 解决方案文件,该文件现在可以在 build\windows 目录中找到,其名称与父级 Flutter 应用的名称一致。

  3. 在“解决方案资源管理器”中,你将看到多个项目。右键单击与 Flutter 应用同名的项目,然后选择设为启动项目

  4. 要生成必要的依赖项,请运行生成 > 生成解决方案

    你也可以按 Ctrl + Shift + B

    要从 Visual Studio 运行 Windows 应用,请转到调试 > 开始调试

    你也可以按 F5

  5. 根据需要使用工具栏在“调试”和“发布”配置之间切换。

分发 Windows 应用

#

你可以使用各种方法来分发你的 Windows 应用程序。以下是一些选项:

  • 使用工具为你的应用构建 MSIX 安装程序(在下一节中描述),并通过 Microsoft Windows 应用商店分发。此选项无需手动创建签名证书,因为它已为你处理。
  • 构建 MSIX 安装程序并通过你自己的网站分发。对于此选项,你需要以 .pfx 证书的形式为你的应用程序提供数字签名。
  • 收集所有必要的组件并构建你自己的 zip 文件。

MSIX 打包

#

MSIX 是新的 Windows 应用程序包格式,提供了一种现代的打包格式和安装程序。此格式可用于将应用程序发布到 Windows 上的 Microsoft Store,或者你可以直接分发应用程序安装程序。

为 Flutter 项目创建 MSIX 分发的最简单方法是使用 msix pub 包。有关从 Flutter 桌面应用使用 msix 包的示例,请参阅 Desktop Photo Search 示例。

为本地测试创建自签名 .pfx 证书

#

对于借助 MSIX 安装程序进行私人部署和测试,你需要以 .pfx 证书的形式为你的应用程序提供数字签名。

通过 Windows 应用商店部署时,无需生成 .pfx 证书。Windows 应用商店负责处理通过其商店分发的应用程序的证书创建和管理。

通过在网站上自托管来分发你的应用程序需要一个由 Windows 信任的证书颁发机构签名的证书。

使用以下说明生成自签名 .pfx 证书。

  1. 如果你还没有,请下载 OpenSSL 工具包以生成你的证书。
  2. 前往你安装 OpenSSL 的位置,例如 C:\Program Files\OpenSSL-Win64\bin
  3. 设置环境变量,以便你可以从任何位置访问 OpenSSL
    "C:\Program Files\OpenSSL-Win64\bin"
  4. 生成私钥如下
    openssl genrsa -out mykeyname.key 2048
  5. 使用私钥生成证书签名请求 (CSR) 文件
    openssl req -new -key mykeyname.key -out mycsrname.csr
  6. 使用私钥和 CSR 文件生成签名证书 (CRT) 文件
    openssl x509 -in mycsrname.csr -out mycrtname.crt -req -signkey mykeyname.key -days 10000
  7. 使用私钥和 CRT 文件生成 .pfx 文件
    openssl pkcs12 -export -out CERTIFICATE.pfx -inkey mykeyname.key -in mycrtname.crt
  8. 在安装应用之前,首先在本地机器的证书存储中将 .pfx 证书安装为受信任的根证书颁发机构

为 Windows 构建自己的 zip 文件

#

Flutter 可执行文件 (.exe) 可以在你的项目中的 build\windows\runner\<build mode>\ 目录下找到。除了该可执行文件,你还需要以下内容:

  • 从同一目录

    • 所有 .dll 文件
    • data 目录
  • Visual C++ 可再发行组件。你可以使用 Microsoft 网站上部署示例演练中显示的任何方法来确保最终用户拥有 C++ 可再发行组件。如果你使用 application-local 选项,你需要复制:

    • msvcp140.dll
    • vcruntime140.dll
    • vcruntime140_1.dll

    将 DLL 文件放在可执行文件和其他 DLL 所在的目录中,并将它们打包成一个 zip 文件。最终的结构看起来像这样:

    Release
    │   flutter_windows.dll
    │   msvcp140.dll
    │   my_app.exe
    │   vcruntime140.dll
    │   vcruntime140_1.dll
    
    └───data
    │   │   app.so
    │   │   icudtl.dat
    
    ...

此时,如果需要,将此文件夹添加到 Windows 安装程序(如 Inno Setup、WiX 等)中会相对简单。

额外资源

#

要了解如何使用 Inno Setup 构建 .exe 文件以分发你的 Flutter Windows 桌面应用,请查阅分步Windows 打包指南