├── .clang-format ├── .github ├── FUNDING.yml └── workflows │ ├── build.yml │ ├── lint.yml │ └── test.yml ├── .gitignore ├── .vscode ├── c_cpp_properties.json └── settings.json ├── LICENSE ├── README-ZH.md ├── README.md ├── docs ├── en │ ├── index.md │ └── quick-start.md └── zh │ ├── index.md │ └── quick-start.md ├── melos.yaml ├── packages ├── auto_updater │ ├── .gitignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README-ZH.md │ ├── README.md │ ├── analysis_options.yaml │ ├── bin │ │ ├── generate_keys.dart │ │ └── sign_update.dart │ ├── dart_dependency_validator.yaml │ ├── example │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── distribute_options.yaml │ │ ├── dsa_priv.pem │ │ ├── dsa_pub.pem │ │ ├── lib │ │ │ ├── main.dart │ │ │ └── pages │ │ │ │ └── home.dart │ │ ├── macos │ │ │ ├── .gitignore │ │ │ ├── Flutter │ │ │ │ ├── Flutter-Debug.xcconfig │ │ │ │ ├── Flutter-Release.xcconfig │ │ │ │ └── GeneratedPluginRegistrant.swift │ │ │ ├── Podfile │ │ │ ├── Podfile.lock │ │ │ ├── Runner.xcodeproj │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace │ │ │ │ │ └── xcshareddata │ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata │ │ │ │ │ └── xcschemes │ │ │ │ │ └── Runner.xcscheme │ │ │ ├── Runner.xcworkspace │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ ├── Runner │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets │ │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ │ ├── Contents.json │ │ │ │ │ │ ├── app_icon_1024.png │ │ │ │ │ │ ├── app_icon_128.png │ │ │ │ │ │ ├── app_icon_16.png │ │ │ │ │ │ ├── app_icon_256.png │ │ │ │ │ │ ├── app_icon_32.png │ │ │ │ │ │ ├── app_icon_512.png │ │ │ │ │ │ └── app_icon_64.png │ │ │ │ ├── Base.lproj │ │ │ │ │ └── MainMenu.xib │ │ │ │ ├── Configs │ │ │ │ │ ├── AppInfo.xcconfig │ │ │ │ │ ├── Debug.xcconfig │ │ │ │ │ ├── Release.xcconfig │ │ │ │ │ └── Warnings.xcconfig │ │ │ │ ├── DebugProfile.entitlements │ │ │ │ ├── Info.plist │ │ │ │ ├── MainFlutterWindow.swift │ │ │ │ └── Release.entitlements │ │ │ └── packaging │ │ │ │ └── dmg │ │ │ │ └── make_config.yaml │ │ ├── pubspec.yaml │ │ └── windows │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ ├── flutter │ │ │ ├── CMakeLists.txt │ │ │ ├── generated_plugin_registrant.cc │ │ │ ├── generated_plugin_registrant.h │ │ │ └── generated_plugins.cmake │ │ │ ├── packaging │ │ │ └── exe │ │ │ │ └── make_config.yaml │ │ │ └── runner │ │ │ ├── CMakeLists.txt │ │ │ ├── Runner.rc │ │ │ ├── flutter_window.cpp │ │ │ ├── flutter_window.h │ │ │ ├── main.cpp │ │ │ ├── resource.h │ │ │ ├── resources │ │ │ └── app_icon.ico │ │ │ ├── runner.exe.manifest │ │ │ ├── utils.cpp │ │ │ ├── utils.h │ │ │ ├── win32_window.cpp │ │ │ └── win32_window.h │ ├── lib │ │ ├── auto_updater.dart │ │ └── src │ │ │ ├── appcast.dart │ │ │ ├── appcast.g.dart │ │ │ ├── auto_updater.dart │ │ │ ├── updater_error.dart │ │ │ └── updater_listener.dart │ └── pubspec.yaml ├── auto_updater_macos │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── macos │ │ ├── Classes │ │ │ ├── AutoUpdater.swift │ │ │ └── AutoUpdaterMacosPlugin.swift │ │ └── auto_updater_macos.podspec │ └── pubspec.yaml ├── auto_updater_platform_interface │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── lib │ │ ├── auto_updater_platform_interface.dart │ │ └── src │ │ │ ├── auto_updater_method_channel.dart │ │ │ └── auto_updater_platform_interface.dart │ └── pubspec.yaml └── auto_updater_windows │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── pubspec.yaml │ └── windows │ ├── .gitignore │ ├── CMakeLists.txt │ ├── WinSparkle-0.8.1 │ ├── ARM64 │ │ └── Release │ │ │ ├── WinSparkle.dll │ │ │ ├── WinSparkle.lib │ │ │ └── WinSparkle.pdb │ ├── AUTHORS │ ├── COPYING │ ├── COPYING.expat │ ├── NEWS │ ├── README.md │ ├── Release │ │ ├── WinSparkle.dll │ │ ├── WinSparkle.lib │ │ └── WinSparkle.pdb │ ├── bin │ │ ├── generate_keys.bat │ │ └── sign_update.bat │ ├── include │ │ ├── winsparkle-version.h │ │ └── winsparkle.h │ └── x64 │ │ └── Release │ │ ├── WinSparkle.dll │ │ ├── WinSparkle.lib │ │ └── WinSparkle.pdb │ ├── auto_updater.cpp │ ├── auto_updater_windows_plugin.cpp │ ├── auto_updater_windows_plugin.h │ ├── auto_updater_windows_plugin_c_api.cpp │ ├── include │ └── auto_updater_windows │ │ └── auto_updater_windows_plugin_c_api.h │ └── test │ └── auto_updater_windows_plugin_test.cpp ├── pubspec.yaml └── screenshots ├── sparkle.png └── winsparkle.png /.clang-format: -------------------------------------------------------------------------------- 1 | # Defines the Chromium style for automatic reformatting. 2 | # http://clang.llvm.org/docs/ClangFormatStyleOptions.html 3 | BasedOnStyle: Chromium 4 | # This defaults to 'Auto'. Explicitly set it for a while, so that 5 | # 'vector >' in existing files gets formatted to 6 | # 'vector>'. ('Auto' means that clang-format will only use 7 | # 'int>>' if the file already contains at least one such instance.) 8 | Standard: Cpp11 9 | SortIncludes: true 10 | --- 11 | Language: ObjC 12 | ColumnLimit: 100 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | liberapay: lijy91 2 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | on: 4 | push: 5 | branches: [main, dev] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | # build-linux: 11 | # runs-on: ubuntu-latest 12 | # steps: 13 | # - uses: actions/checkout@v3 14 | # - uses: subosito/flutter-action@v2 15 | # with: 16 | # flutter-version: "3.24.3" 17 | # channel: "stable" 18 | # - run: | 19 | # sudo apt-get update 20 | # sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev 21 | # sudo apt-get install -y keybinder-3.0 22 | # - uses: bluefireteam/melos-action@v3 23 | # - working-directory: ./packages/auto_updater/example 24 | # run: | 25 | # flutter build linux --release 26 | 27 | build-macos: 28 | runs-on: macos-latest 29 | steps: 30 | - uses: actions/checkout@v3 31 | - uses: subosito/flutter-action@v2 32 | with: 33 | flutter-version: "3.24.3" 34 | channel: "stable" 35 | - uses: bluefireteam/melos-action@v3 36 | - working-directory: ./packages/auto_updater/example 37 | run: | 38 | flutter build macos --release 39 | 40 | # build-web: 41 | # runs-on: macos-latest 42 | # steps: 43 | # - uses: actions/checkout@v3 44 | # - uses: subosito/flutter-action@v2 45 | # with: 46 | # flutter-version: "3.24.3" 47 | # channel: "stable" 48 | # - uses: bluefireteam/melos-action@v3 49 | # - working-directory: ./packages/auto_updater/example 50 | # run: | 51 | # flutter build web --release 52 | 53 | build-windows: 54 | runs-on: windows-latest 55 | steps: 56 | - uses: actions/checkout@v3 57 | - uses: subosito/flutter-action@v2 58 | with: 59 | flutter-version: "3.24.3" 60 | channel: "stable" 61 | - uses: bluefireteam/melos-action@v3 62 | - working-directory: ./packages/auto_updater/example 63 | run: | 64 | flutter build windows --release 65 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: lint 2 | 3 | on: 4 | push: 5 | branches: [main, dev] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | analyze: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: subosito/flutter-action@v2 15 | with: 16 | flutter-version: "3.24.3" 17 | channel: "stable" 18 | - uses: bluefireteam/melos-action@v3 19 | - run: melos run analyze 20 | 21 | format: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v3 25 | - uses: subosito/flutter-action@v2 26 | with: 27 | flutter-version: "3.24.3" 28 | channel: "stable" 29 | cache: true 30 | - uses: bluefireteam/melos-action@v3 31 | - run: melos run format-check 32 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | on: 4 | push: 5 | branches: [main, dev] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v3 14 | - uses: subosito/flutter-action@v2 15 | with: 16 | flutter-version: "3.24.3" 17 | channel: "stable" 18 | cache: true 19 | - uses: bluefireteam/melos-action@v3 20 | - run: melos run test --no-select 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .dart_tool/ 2 | .idea/ 3 | 4 | *.iml 5 | pubspec_overrides.yaml 6 | pubspec.lock 7 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Win32", 5 | "includePath": [ 6 | "${workspaceFolder}/**" 7 | ], 8 | "defines": [ 9 | "_DEBUG", 10 | "UNICODE", 11 | "_UNICODE" 12 | ], 13 | "windowsSdkVersion": "10.0.22000.0", 14 | "compilerPath": "cl.exe", 15 | "cStandard": "c17", 16 | "cppStandard": "c++17", 17 | "intelliSenseMode": "windows-msvc-x64" 18 | } 19 | ], 20 | "version": 4 21 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "algorithm": "cpp", 4 | "array": "cpp", 5 | "atomic": "cpp", 6 | "bit": "cpp", 7 | "cctype": "cpp", 8 | "charconv": "cpp", 9 | "chrono": "cpp", 10 | "clocale": "cpp", 11 | "cmath": "cpp", 12 | "codecvt": "cpp", 13 | "compare": "cpp", 14 | "concepts": "cpp", 15 | "cstddef": "cpp", 16 | "cstdint": "cpp", 17 | "cstdio": "cpp", 18 | "cstdlib": "cpp", 19 | "cstring": "cpp", 20 | "ctime": "cpp", 21 | "cwchar": "cpp", 22 | "exception": "cpp", 23 | "format": "cpp", 24 | "forward_list": "cpp", 25 | "functional": "cpp", 26 | "initializer_list": "cpp", 27 | "iomanip": "cpp", 28 | "ios": "cpp", 29 | "iosfwd": "cpp", 30 | "iostream": "cpp", 31 | "istream": "cpp", 32 | "iterator": "cpp", 33 | "limits": "cpp", 34 | "list": "cpp", 35 | "locale": "cpp", 36 | "map": "cpp", 37 | "memory": "cpp", 38 | "new": "cpp", 39 | "optional": "cpp", 40 | "ostream": "cpp", 41 | "ratio": "cpp", 42 | "set": "cpp", 43 | "sstream": "cpp", 44 | "stdexcept": "cpp", 45 | "streambuf": "cpp", 46 | "string": "cpp", 47 | "system_error": "cpp", 48 | "tuple": "cpp", 49 | "type_traits": "cpp", 50 | "typeinfo": "cpp", 51 | "unordered_map": "cpp", 52 | "utility": "cpp", 53 | "variant": "cpp", 54 | "vector": "cpp", 55 | "xfacet": "cpp", 56 | "xhash": "cpp", 57 | "xiosbase": "cpp", 58 | "xlocale": "cpp", 59 | "xlocbuf": "cpp", 60 | "xlocinfo": "cpp", 61 | "xlocmes": "cpp", 62 | "xlocmon": "cpp", 63 | "xlocnum": "cpp", 64 | "xloctime": "cpp", 65 | "xmemory": "cpp", 66 | "xstddef": "cpp", 67 | "xstring": "cpp", 68 | "xtr1common": "cpp", 69 | "xtree": "cpp", 70 | "xutility": "cpp", 71 | "any": "cpp" 72 | } 73 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 LiJianying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README-ZH.md: -------------------------------------------------------------------------------- 1 | > **🚀 快速发布您的应用**: 试试 [Fastforge](https://fastforge.dev) - 构建、打包和分发您的 Flutter 应用最简单的方式。 2 | 3 | # auto_updater 4 | 5 | [![pub version][pub-image]][pub-url] [![][discord-image]][discord-url] 6 | 7 | [pub-image]: https://img.shields.io/pub/v/auto_updater.svg 8 | [pub-url]: https://pub.dev/packages/auto_updater 9 | [discord-image]: https://img.shields.io/discord/884679008049037342.svg 10 | [discord-url]: https://discord.gg/zPa6EZ2jqb 11 | 12 | 这个插件允许 Flutter **桌面** 应用自动更新自己 (基于 [sparkle](https://sparkle-project.org/) 和 [winsparkle](https://winsparkle.org))。 13 | 14 | 15 | 16 | --- 17 | 18 | [English](./README.md) | 简体中文 19 | 20 | --- 21 | 22 | 23 | 24 | 25 | - [平台支持](#%E5%B9%B3%E5%8F%B0%E6%94%AF%E6%8C%81) 26 | - [文档](#%E6%96%87%E6%A1%A3) 27 | - [谁在用使用它?](#%E8%B0%81%E5%9C%A8%E7%94%A8%E4%BD%BF%E7%94%A8%E5%AE%83) 28 | - [API](#api) 29 | - [AutoUpdater](#autoupdater) 30 | - [Methods](#methods) 31 | - [setFeedURL](#setfeedurl) 32 | - [checkForUpdates](#checkforupdates) 33 | - [setScheduledCheckInterval](#setscheduledcheckinterval) 34 | - [相关链接](#%E7%9B%B8%E5%85%B3%E9%93%BE%E6%8E%A5) 35 | - [许可证](#%E8%AE%B8%E5%8F%AF%E8%AF%81) 36 | 37 | 38 | 39 | ## 平台支持 40 | 41 | | Linux | macOS | Windows | 42 | | :---: | :---: | :-----: | 43 | | ➖ | ✔️ | ✔️ | 44 | 45 | ## 文档 46 | 47 | - [快速开始](https://leanflutter.dev/zh/documentation/auto_updater/quick-start) 48 | - [API 参考](https://pub.dev/documentation/auto_updater/latest/auto_updater/) 49 | - [更新日志](https://pub.dev/packages/auto_updater/changelog) 50 | 51 | ## 谁在用使用它? 52 | 53 | - [比译](https://biyidev.com/) - 一个便捷的翻译和词典应用程序。 54 | 55 | ## API 56 | 57 | 58 | 59 | ### AutoUpdater 60 | 61 | #### Methods 62 | 63 | ##### setFeedURL 64 | 65 | 设置 url 并初始化 auto updater. 66 | 67 | ##### checkForUpdates 68 | 69 | 检查更新,在此之前必须先调用 setFeedURL. 70 | 71 | ##### setScheduledCheckInterval 72 | 73 | 设置检查时间间隔,默认 86400,最少 3600, 0 不更新 74 | 75 | 76 | 77 | ## 相关链接 78 | 79 | - https://sparkle-project.org/ 80 | - https://winsparkle.org/ 81 | 82 | ## 许可证 83 | 84 | [MIT](./LICENSE) 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > **🚀 Ship Your App Faster**: Try [Fastforge](https://fastforge.dev) - The simplest way to build, package and distribute your Flutter apps. 2 | 3 | # auto_updater 4 | 5 | [![pub version][pub-image]][pub-url] [![][discord-image]][discord-url] 6 | 7 | [pub-image]: https://img.shields.io/pub/v/auto_updater.svg 8 | [pub-url]: https://pub.dev/packages/auto_updater 9 | [discord-image]: https://img.shields.io/discord/884679008049037342.svg 10 | [discord-url]: https://discord.gg/zPa6EZ2jqb 11 | 12 | This plugin allows Flutter **desktop** apps to automatically update themselves (based on [sparkle](https://sparkle-project.org/) and [winsparkle](https://winsparkle.org)). 13 | 14 | 15 | 16 | --- 17 | 18 | English | [简体中文](./README-ZH.md) 19 | 20 | --- 21 | 22 | 23 | 24 | 25 | - [Platform Support](#platform-support) 26 | - [Documentation](#documentation) 27 | - [Who's using it?](#whos-using-it) 28 | - [API](#api) 29 | - [AutoUpdater](#autoupdater) 30 | - [Methods](#methods) 31 | - [setFeedURL](#setfeedurl) 32 | - [checkForUpdates](#checkforupdates) 33 | - [setScheduledCheckInterval](#setscheduledcheckinterval) 34 | - [Related Links](#related-links) 35 | - [License](#license) 36 | 37 | 38 | 39 | ## Platform Support 40 | 41 | | Linux | macOS | Windows | 42 | | :---: | :---: | :-----: | 43 | | ➖ | ✔️ | ✔️ | 44 | 45 | ## Documentation 46 | 47 | - [Quick Start](https://leanflutter.dev/documentation/auto_updater/quick-start) 48 | - [API Reference](https://pub.dev/documentation/auto_updater/latest/auto_updater/) 49 | - [Changelog](https://pub.dev/packages/auto_updater/changelog) 50 | 51 | ## Who's using it? 52 | 53 | - [Biyi](https://biyidev.com/) - A convenient translation and dictionary app. 54 | 55 | ## API 56 | 57 | 58 | 59 | ### AutoUpdater 60 | 61 | #### Methods 62 | 63 | ##### setFeedURL 64 | 65 | Sets the url and initialize the auto updater. 66 | 67 | ##### checkForUpdates 68 | 69 | Asks the server whether there is an update. You must call setFeedURL before using this API. 70 | 71 | ##### setScheduledCheckInterval 72 | 73 | Sets the auto update check interval, default 86400, minimum 3600, 0 to disable update 74 | 75 | 76 | 77 | ## Related Links 78 | 79 | - https://sparkle-project.org/ 80 | - https://winsparkle.org/ 81 | 82 | ## License 83 | 84 | [MIT](./LICENSE) 85 | -------------------------------------------------------------------------------- /docs/en/index.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | This plugin allows Flutter **desktop** apps to automatically update themselves (based on [sparkle](https://sparkle-project.org/) and [winsparkle](https://winsparkle.org)). 4 | 5 | 6 | 7 |
8 | 9 | auto_updater on GitHub 13 | 14 | 15 | Pub Likes 16 | 17 |
18 | 19 | ## Platform Support 20 | 21 | | Linux | macOS | Windows | 22 | | :---: | :---: | :-----: | 23 | | ➖ | ✔️ | ✔️ | 24 | -------------------------------------------------------------------------------- /docs/en/quick-start.md: -------------------------------------------------------------------------------- 1 | # Quick Start 2 | 3 | Follow the steps below to quickly get started with the `auto_updater` plugin: 4 | 5 | ## Installation 6 | 7 | Add this to your package's pubspec.yaml file: 8 | 9 | ```yaml 10 | dependencies: 11 | auto_updater: ^0.2.0 12 | ``` 13 | 14 | Or 15 | 16 | ```yaml 17 | dependencies: 18 | auto_updater: 19 | git: 20 | path: packages/auto_updater 21 | url: https://github.com/leanflutter/auto_updater.git 22 | ref: main 23 | ``` 24 | 25 | ### ⚠️ Windows requirements 26 | 27 | - `openssl` 28 | 29 | Run the following command: 30 | 31 | > Use [Chocolatey](https://chocolatey.org/install) 32 | 33 | ``` 34 | choco install openssl 35 | ``` 36 | 37 | ## Usage 38 | 39 | ```dart 40 | import 'package:auto_updater/auto_updater.dart'; 41 | 42 | void main() async { 43 | // Must add this line. 44 | WidgetsFlutterBinding.ensureInitialized(); 45 | 46 | String feedURL = 'http://localhost:5002/appcast.xml'; 47 | await autoUpdater.setFeedURL(feedURL); 48 | await autoUpdater.checkForUpdates(); 49 | await autoUpdater.setScheduledCheckInterval(3600); 50 | 51 | runApp(MyApp()); 52 | } 53 | ``` 54 | 55 | > Please see the example app of this plugin for a full example. 56 | 57 | ## Publish your app 58 | 59 | ### Generate private key 60 | 61 | Run the following command: 62 | 63 | ```bash 64 | dart run auto_updater:generate_keys 65 | ``` 66 | 67 | > You need to run this command on `macOS` and `Windows` systems separately. 68 | 69 | #### macOS 70 | 71 | Prepare signing with `EdDSA` signatures: 72 | 73 | Output: 74 | 75 | ``` 76 | A key has been generated and saved in your keychain. Add the `SUPublicEDKey` key to 77 | the Info.plist of each app for which you intend to use Sparkle for distributing 78 | updates. It should appear like this: 79 | 80 | SUPublicEDKey 81 | pfIShU4dEXqPd5ObYNfDBiQWcXozk7estwzTnF9BamQ= 82 | ``` 83 | 84 | Change the file `macos/Runner/Info.plist` as follows: 85 | 86 | ```diff 87 | 88 | 89 | 90 | 91 | 92 | ... 93 | 94 | + SUPublicEDKey 95 | + bHaXClrRGMmKoKP/3HJnr/jn2ODTRPAM3VZhhkI9ZvY= 96 | 97 | 98 | ``` 99 | 100 | #### Windows 101 | 102 | Prepare signing with `DSA` signatures: 103 | 104 | Output: 105 | 106 | ``` 107 | Generated two files: 108 | dsa_priv.pem: your private key. Keep it secret and don't share it! 109 | dsa_pub.pem: public counterpart to include in youe app. 110 | BACK UP YOUR PRIVATE KEY AND KEEP IT SAFE! 111 | If you lose it, your users will be unable to upgrade! 112 | ``` 113 | 114 | > command will generate the private key (`dsa_priv.pem`) and the public key (`dsa_pub.pem`) for you. Please Back up your private key and keep it safe, Add your public key to your project either as Windows resource. 115 | 116 | Change the file `windows/runner/Runner.rc` as follows: 117 | 118 | ```diff 119 | 120 | ... 121 | 122 | +///////////////////////////////////////////////////////////////////////////// 123 | +// 124 | +// WinSparkle 125 | +// 126 | 127 | +// And verify signature using DSA public key: 128 | +DSAPub DSAPEM "../../dsa_pub.pem" 129 | ``` 130 | 131 | ### Packaging 132 | 133 | > To simplify the packaging process, [Fastforge](https://fastforge.dev) is used here, A complete tool dedicated to packaging and publishing Flutter apps. 134 | 135 | Add `distribute_options.yaml` to your project root directory. 136 | 137 | ```yaml 138 | output: dist/ 139 | releases: 140 | - name: prod 141 | jobs: 142 | - name: macos-zip 143 | package: 144 | platform: macos 145 | target: zip 146 | build_args: 147 | dart-define: 148 | APP_ENV: dev 149 | # See full documentation: https://fastforge.dev/makers/exe 150 | - name: windows-exe 151 | package: 152 | platform: windows 153 | target: exe 154 | build_args: 155 | dart-define: 156 | APP_ENV: dev 157 | ``` 158 | 159 | #### macOS 160 | 161 | Run the following command: 162 | 163 | ``` 164 | fastforge release --name prod --jobs macos-zip 165 | ``` 166 | 167 | #### Windows 168 | 169 | Run the following command: 170 | 171 | ``` 172 | fastforge release --name prod --jobs windows-exe 173 | ``` 174 | 175 | ### Get signature 176 | 177 | #### macOS 178 | 179 | Run the following command: 180 | 181 | ``` 182 | dart run auto_updater:sign_update dist/1.1.0+2/auto_updater_example-1.1.0+2-macos.zip 183 | ``` 184 | 185 | Output: 186 | 187 | ``` 188 | sparkle:edSignature="pbdyPt92pnPkzLfQ7BhS9hbjcV9/ndkzSIlWjFQIUMcaCNbAFO2fzl0tISMNJApG2POTkZY0/kJQ2yZYOSVgAA==" length="13400992" 189 | ``` 190 | 191 | Update the obtained new signature to the value of the `sparkle:edSignature` attribute of the `enclosure` node of the `appcast.xml` file. 192 | 193 | #### Windows 194 | 195 | Run the following command: 196 | 197 | ``` 198 | dart run auto_updater:sign_update dist/1.1.0+2/auto_updater_example-1.1.0+2-windows-setup.exe 199 | ``` 200 | 201 | Output: 202 | 203 | ``` 204 | 205 | sparkle:dsaSignature="MEUCIQCVbVzVID7H3aUzAY5znpi+ySZKznkukV8whlMFzKh66AIgREUGOmvavlcg6hwAwkb2o4IqVE/D56ipIBshIqCH8rk=" length="13400992" 206 | ``` 207 | 208 | Update the obtained new signature to the value of the `sparkle:dsaSignature` attribute of the `enclosure` node of the `appcast.xml` file. 209 | 210 | ### Distributing 211 | 212 | Add `appcast.xml` to your project `dist/` directory. 213 | 214 | ```xml 215 | 216 | 217 | 218 | auto_updater_example 219 | Most recent updates to auto_updater_example 220 | en 221 | 222 | Version 1.1.0 223 | 224 | 2 225 | 1.1.0 226 | 227 | https://your_domain/your_path/release_notes.html 228 | 229 | Sun, 16 Feb 2022 12:00:00 +0800 230 | 235 | 236 | 237 | Version 1.1.0 238 | 239 | https://your_domain/your_path/release_notes.html 240 | 241 | Sun, 16 Feb 2022 12:00:00 +0800 242 | 248 | 249 | 250 | 251 | ``` 252 | 253 | > This example uses the same `appcast.xml` file for `macOS` and `Windows`, and you need to configure the value of the `sparkle:os` property accordingly. 254 | 255 | Start the test update server: 256 | 257 | ``` 258 | cd dist/ 259 | serve -l 5002 260 | ``` 261 | 262 | ## Troubleshooting 263 | 264 | ### macOS 265 | 266 | - Make sure you have the sparkle pod added as described in [Sparkle Documentation](https://sparkle-project.org/documentation/) 267 | - Make sure you have added and enabled network capabilties of your app and disabled the sandbox for release by adding the following to your entitlement files for debug and release 268 | 269 | ``` 270 | com.apple.security.network.client 271 | 272 | com.apple.security.network.server 273 | 274 | com.apple.security.app-sandbox 275 | 276 | ``` 277 | -------------------------------------------------------------------------------- /docs/zh/index.md: -------------------------------------------------------------------------------- 1 | # 介绍 2 | 3 | 这个插件允许 Flutter **桌面** 应用自动更新自己 (基于 [sparkle](https://sparkle-project.org/) 和 [winsparkle](https://winsparkle.org))。 4 | 5 | 6 | 7 | 18 | 19 | ## 平台支持 20 | 21 | | Linux | macOS | Windows | 22 | | :---: | :---: | :-----: | 23 | | ➖ | ✔️ | ✔️ | 24 | -------------------------------------------------------------------------------- /docs/zh/quick-start.md: -------------------------------------------------------------------------------- 1 | # 快速开始 2 | 3 | 按照以下步骤快速开始使用 `auto_updater` 插件: 4 | 5 | ## 安装 6 | 7 | 将此添加到你的软件包的 pubspec.yaml 文件: 8 | 9 | ```yaml 10 | dependencies: 11 | auto_updater: ^0.2.0 12 | ``` 13 | 14 | 或 15 | 16 | ```yaml 17 | dependencies: 18 | auto_updater: 19 | git: 20 | path: packages/auto_updater 21 | url: https://github.com/leanflutter/auto_updater.git 22 | ref: main 23 | ``` 24 | 25 | ### ⚠️ Windows requirements 26 | 27 | - `openssl` 28 | 29 | 运行以下命令: 30 | 31 | > 使用 [Chocolatey](https://chocolatey.org/install) 32 | 33 | ``` 34 | choco install openssl 35 | ``` 36 | 37 | ## 用法 38 | 39 | ```dart 40 | import 'package:auto_updater/auto_updater.dart'; 41 | 42 | void main() async { 43 | // 必须加上这一行。 44 | WidgetsFlutterBinding.ensureInitialized(); 45 | 46 | String feedURL = 'http://localhost:5002/appcast.xml'; 47 | await autoUpdater.setFeedURL(feedURL); 48 | await autoUpdater.checkForUpdates(); 49 | await autoUpdater.setScheduledCheckInterval(3600); 50 | 51 | runApp(MyApp()); 52 | } 53 | ``` 54 | 55 | > 请看这个插件的示例应用,以了解完整的例子。 56 | 57 | ## 发布你的应用 58 | 59 | ### 生成私钥 60 | 61 | 运行以下命令: 62 | 63 | ```bash 64 | dart run auto_updater:generate_keys 65 | ``` 66 | 67 | > 需要分别在 `macOS` 和 `Windows` 系统中运行该命令。 68 | 69 | #### macOS 70 | 71 | 准备使用 `EdDSA` 签名算法进行签名: 72 | 73 | 输出: 74 | 75 | ``` 76 | A key has been generated and saved in your keychain. Add the `SUPublicEDKey` key to 77 | the Info.plist of each app for which you intend to use Sparkle for distributing 78 | updates. It should appear like this: 79 | 80 | SUPublicEDKey 81 | pfIShU4dEXqPd5ObYNfDBiQWcXozk7estwzTnF9BamQ= 82 | ``` 83 | 84 | 更改文件 `macos/Runner/Info.plist` 如下: 85 | 86 | ```diff 87 | 88 | 89 | 90 | 91 | 92 | ... 93 | 94 | + SUPublicEDKey 95 | + bHaXClrRGMmKoKP/3HJnr/jn2ODTRPAM3VZhhkI9ZvY= 96 | 97 | 98 | ``` 99 | 100 | #### Windows 101 | 102 | 准备使用 `DSA` 签名算法进行签名: 103 | 104 | 输出: 105 | 106 | ``` 107 | Generated two files: 108 | dsa_priv.pem: your private key. Keep it secret and don't share it! 109 | dsa_pub.pem: public counterpart to include in youe app. 110 | BACK UP YOUR PRIVATE KEY AND KEEP IT SAFE! 111 | If you lose it, your users will be unable to upgrade! 112 | ``` 113 | 114 | > 命令将为你生成私钥(`dsa_priv.pem`)及公钥(`dsa_pub.pem`),请备份你的私钥并确保其安全,并将公钥作为 Windows 资源添加到项目中。 115 | 116 | 更改文件 `windows/runner/Runner.rc` 如下: 117 | 118 | ```diff 119 | 120 | ... 121 | 122 | +///////////////////////////////////////////////////////////////////////////// 123 | +// 124 | +// WinSparkle 125 | +// 126 | 127 | +// And verify signature using DSA public key: 128 | +DSAPub DSAPEM "../../dsa_pub.pem" 129 | ``` 130 | 131 | ### 打包应用 132 | 133 | > 为了简化打包的过程,这里使用了 [Fastforge](https://fastforge.dev) ,一个专门用于打包和发布 Flutter 应用的完整工具。 134 | 135 | 将 `distribute_options.yaml` 添加到你的项目根目录。 136 | 137 | ```yaml 138 | output: dist/ 139 | releases: 140 | - name: prod 141 | jobs: 142 | - name: macos-zip 143 | package: 144 | platform: macos 145 | target: zip 146 | build_args: 147 | dart-define: 148 | APP_ENV: dev 149 | # 查看完整文档:https://fastforge.dev/makers/exe 150 | - name: windows-exe 151 | package: 152 | platform: windows 153 | target: exe 154 | build_args: 155 | dart-define: 156 | APP_ENV: dev 157 | ``` 158 | 159 | #### macOS 160 | 161 | 运行以下命令: 162 | 163 | ``` 164 | fastforge release --name prod --jobs macos-zip 165 | ``` 166 | 167 | #### Windows 168 | 169 | 运行以下命令: 170 | 171 | ``` 172 | fastforge release --name prod --jobs windows-exe 173 | ``` 174 | 175 | ### 获取签名 176 | 177 | #### macOS 178 | 179 | 运行以下命令: 180 | 181 | ``` 182 | dart run auto_updater:sign_update dist/1.1.0+2/auto_updater_example-1.1.0+2-macos.zip 183 | ``` 184 | 185 | 输出: 186 | 187 | ``` 188 | sparkle:edSignature="pbdyPt92pnPkzLfQ7BhS9hbjcV9/ndkzSIlWjFQIUMcaCNbAFO2fzl0tISMNJApG2POTkZY0/kJQ2yZYOSVgAA==" length="13400992" 189 | ``` 190 | 191 | 将获得的新签名更新到 `appcast.xml` 文件 `enclosure` 节点的 `sparkle:edSignature` 属性值。 192 | 193 | #### Windows 194 | 195 | 运行以下命令: 196 | 197 | ``` 198 | dart run auto_updater:sign_update dist/1.1.0+2/auto_updater_example-1.1.0+2-windows-setup.exe 199 | ``` 200 | 201 | 输出: 202 | 203 | ``` 204 | 205 | sparkle:dsaSignature="MEUCIQCVbVzVID7H3aUzAY5znpi+ySZKznkukV8whlMFzKh66AIgREUGOmvavlcg6hwAwkb2o4IqVE/D56ipIBshIqCH8rk=" length="13400992" 206 | ``` 207 | 208 | 将获得的新签名更新到 `appcast.xml` 文件 `enclosure` 节点的 `sparkle:dsaSignature` 属性值。 209 | 210 | ### 分发应用 211 | 212 | 将 `appcast.xml` 添加到你的项目 `dist/` 目录。 213 | 214 | ```xml 215 | 216 | 217 | 218 | auto_updater_example 219 | Most recent updates to auto_updater_example 220 | en 221 | 222 | Version 1.1.0 223 | 224 | 2 225 | 1.1.0 226 | 227 | https://your_domain/your_path/release_notes.html 228 | 229 | Sun, 16 Feb 2022 12:00:00 +0800 230 | 235 | 236 | 237 | Version 1.1.0 238 | 239 | https://your_domain/your_path/release_notes.html 240 | 241 | Sun, 16 Feb 2022 12:00:00 +0800 242 | 248 | 249 | 250 | 251 | ``` 252 | 253 | > 本示例中 `macOS` 和 `Windows` 使用同一个 `appcast.xml` 文件,你需根据配置 `sparkle:os` 属性的值。 254 | 255 | 启动测试更新服务器: 256 | 257 | ``` 258 | cd dist/ 259 | serve -l 5002 260 | ``` 261 | 262 | ## 故障排除 263 | 264 | ### macOS 265 | 266 | - 确保按照 [Sparkle 文档](https://sparkle-project.org/documentation/)中的说明添加了 sparkle pod 267 | - 通过将以下内容添加到您的授权文件以进行调试和发布,确保您已添加并启用应用程序的网络功能并禁用沙箱以进行发布 268 | 269 | ``` 270 | com.apple.security.network.client 271 | 272 | com.apple.security.network.server 273 | 274 | com.apple.security.app-sandbox 275 | 276 | ``` 277 | -------------------------------------------------------------------------------- /melos.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater_workspace 2 | repository: https://github.com/leanflutter/auto_updater 3 | 4 | packages: 5 | - examples/** 6 | - packages/** 7 | 8 | command: 9 | bootstrap: 10 | # Uses the pubspec_overrides.yaml instead of having Melos modifying the lock file. 11 | usePubspecOverrides: true 12 | 13 | scripts: 14 | analyze: 15 | exec: flutter analyze --fatal-infos 16 | description: Run `flutter analyze` for all packages. 17 | 18 | test: 19 | exec: flutter test 20 | description: Run `flutter test` for a specific package. 21 | packageFilters: 22 | dirExists: 23 | - test 24 | 25 | format: 26 | exec: dart format . --fix 27 | description: Run `dart format` for all packages. 28 | 29 | format-check: 30 | exec: dart format . --fix --set-exit-if-changed 31 | description: Run `dart format` checks for all packages. 32 | 33 | fix: 34 | exec: dart fix . --apply 35 | description: Run `dart fix` for all packages. 36 | -------------------------------------------------------------------------------- /packages/auto_updater/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /packages/auto_updater/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | * First major release. 4 | * [macos] Solve deprecate 'setFeedURL' (#66) 5 | 6 | ## 0.2.1 7 | 8 | * chore(windows): Support before-quit-for-update event 9 | 10 | ## 0.2.0 11 | 12 | * feat: Convert to federated plugin 13 | * feat: Add `UpdaterListener` to listen for update events 14 | * chore: [windows] Upgrade to `WinSparkle-0.8.1` 15 | 16 | ## 0.1.7 17 | 18 | * Bump flutter to 3.10.2 19 | * [windows] fix sign_update script on 3.10.x #49 #37 20 | * [windows] Upgrade to `WinSparkle-0.8.0` (#45) 21 | * [windows] feat: add support for emitting events from winsparkle (#43) 22 | 23 | ## 0.1.6 24 | 25 | * Add `setScheduledCheckInterval` method #28 26 | 27 | ## 0.1.5 28 | 29 | * Add check update in background. 30 | 31 | ## 0.1.4 32 | 33 | * Downgrade flutter version to 2.0.0 #7 34 | 35 | ## 0.1.3 36 | 37 | * [windows] Add missing WinSparkle dll/lib/pdb files #4 38 | * [windows] fix command path error #5 39 | 40 | ## 0.1.2 41 | 42 | * [windows] Add missing WinSparkle dll/lib/pdb files 43 | 44 | ## 0.1.1 45 | 46 | * Downgrade dart sdk version to 2.12.0 47 | 48 | ## 0.1.0 49 | 50 | * first release. 51 | -------------------------------------------------------------------------------- /packages/auto_updater/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 LiJianying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/auto_updater/README-ZH.md: -------------------------------------------------------------------------------- 1 | ../../README-ZH.md -------------------------------------------------------------------------------- /packages/auto_updater/README.md: -------------------------------------------------------------------------------- 1 | ../../README.md -------------------------------------------------------------------------------- /packages/auto_updater/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:mostly_reasonable_lints/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /packages/auto_updater/bin/generate_keys.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | import 'package:path/path.dart' as p; 4 | 5 | Future main(List arguments) async { 6 | if (!(Platform.isMacOS || Platform.isWindows)) { 7 | throw UnsupportedError('auto_updater:generate_keys'); 8 | } 9 | 10 | String executable = Platform.isMacOS 11 | ? '${Directory.current.path}/macos/Pods/Sparkle/bin/generate_keys' 12 | : p.joinAll( 13 | [ 14 | Directory.current.path, 15 | 'windows', 16 | 'flutter', 17 | 'ephemeral', 18 | '.plugin_symlinks', 19 | 'auto_updater_windows', 20 | 'windows', 21 | 'WinSparkle-0.8.1', 22 | 'bin', 23 | 'generate_keys.bat', 24 | ], 25 | ); 26 | 27 | Process process = await Process.start( 28 | executable, 29 | arguments, 30 | ); 31 | 32 | process.stdout.transform(utf8.decoder).listen(stdout.write); 33 | process.stderr.transform(utf8.decoder).listen(stderr.write); 34 | } 35 | -------------------------------------------------------------------------------- /packages/auto_updater/bin/sign_update.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'package:path/path.dart' as p; 3 | 4 | class SignUpdateResult { 5 | const SignUpdateResult({ 6 | required this.signature, 7 | required this.length, 8 | }); 9 | 10 | final String signature; 11 | final int length; 12 | } 13 | 14 | SignUpdateResult signUpdate(List args) { 15 | String executable = Platform.isMacOS 16 | ? '${Directory.current.path}/macos/Pods/Sparkle/bin/sign_update' 17 | : p.joinAll( 18 | [ 19 | Directory.current.path, 20 | 'windows', 21 | 'flutter', 22 | 'ephemeral', 23 | '.plugin_symlinks', 24 | 'auto_updater_windows', 25 | 'windows', 26 | 'WinSparkle-0.8.1', 27 | 'bin', 28 | 'sign_update.bat', 29 | ], 30 | ); 31 | List arguments = List.from(args); 32 | if (Platform.isWindows) { 33 | if (arguments.length == 1) { 34 | arguments.add(p.join('dsa_priv.pem')); 35 | } 36 | } 37 | 38 | ProcessResult processResult = Process.runSync( 39 | executable, 40 | arguments, 41 | ); 42 | 43 | int exitCode = processResult.exitCode; 44 | 45 | String? signUpdateOutput; 46 | if (exitCode == 0) { 47 | signUpdateOutput = processResult.stdout.toString(); 48 | if (Platform.isWindows) { 49 | signUpdateOutput = signUpdateOutput.replaceFirst('\r\n', '').trim(); 50 | signUpdateOutput = 'sparkle:dsaSignature="$signUpdateOutput" length="0"'; 51 | } 52 | stdout.write(signUpdateOutput); 53 | } else { 54 | stderr.write(processResult.stderr); 55 | } 56 | 57 | RegExp regex = RegExp(r'sparkle:(dsa|ed)Signature="([^"]+)" length="(\d+)"'); 58 | RegExpMatch? match = regex.firstMatch(signUpdateOutput!); 59 | 60 | if (match == null) { 61 | throw Exception('Failed to sign update'); 62 | } 63 | return SignUpdateResult( 64 | signature: match.group(2)!, 65 | length: int.tryParse(match.group(3)!)!, 66 | ); 67 | } 68 | 69 | Future main(List args) async { 70 | if (!(Platform.isMacOS || Platform.isWindows)) { 71 | throw UnsupportedError('auto_updater:sign_update'); 72 | } 73 | signUpdate(args); 74 | } 75 | -------------------------------------------------------------------------------- /packages/auto_updater/dart_dependency_validator.yaml: -------------------------------------------------------------------------------- 1 | exclude: 2 | - "example/**" 3 | -------------------------------------------------------------------------------- /packages/auto_updater/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | 48 | /dist/ 49 | -------------------------------------------------------------------------------- /packages/auto_updater/example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled. 5 | 6 | version: 7 | revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2 8 | channel: stable 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2 17 | base_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2 18 | - platform: windows 19 | create_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2 20 | base_revision: d3d8effc686d73e0114d71abdcccef63fa1f25d2 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /packages/auto_updater/example/README.md: -------------------------------------------------------------------------------- 1 | # auto_updater_example 2 | 3 | Demonstrates how to use the auto_updater plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /packages/auto_updater/example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:mostly_reasonable_lints/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /packages/auto_updater/example/distribute_options.yaml: -------------------------------------------------------------------------------- 1 | output: dist/ 2 | releases: 3 | - name: prod 4 | jobs: 5 | - name: macos-zip 6 | package: 7 | platform: macos 8 | target: zip 9 | build_args: 10 | dart-define: 11 | APP_ENV: dev 12 | - name: windows-exe 13 | package: 14 | platform: windows 15 | target: exe 16 | build_args: 17 | dart-define: 18 | APP_ENV: dev 19 | -------------------------------------------------------------------------------- /packages/auto_updater/example/dsa_priv.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN DSA PRIVATE KEY----- 2 | MIIGVgIBAAKCAgEAwQUsUvicpkraOyUg0PbK9dlSsct8jQ7+IB3MbqQgyfpi/1C2 3 | L1I0hC4f41PJeSjBdjXrwM127Dnj5XC3LGgfGfQ2yY5W7mFBcNXngWgr1NAcu7Ki 4 | viXmMExsx0PufC6LGVP9mSowcgQcdzDWLUSS+1/GIAOZbP7i16YU0h+89HsSOxec 5 | 0K5ebTtIWzt9y7/zQI/QV6hTXPxDvpxl2YqyptO4ruYmgP3UWtBh3tsbTX8OeTj4 6 | B7VUSX9+Cah5Ji0N/LEACMwv/o8s+cmJ7ss9SvEp5Gzx/4o+ze35FGSuG2qmgZZx 7 | k926q31iejYvQsgVENcjrq7XdIGQefvDbHkEUfJIQ6+ccjwJ++4yGYpRVbFEedWm 8 | UHnNS07Bq2UoyUUSRJkXAHfNFCuqkdpV6fkkov8dHVLUONQjDyDB6J8zAYiEUNSj 9 | 0dxyL1AKzJ3RcNbQjBCllwwWk6QySYiHl5fRpFwWf+1l0BBrS4cm6UL+UgvRfCYl 10 | ksXmyyfrMEfBtmvr9HjjvutOvoGcTcOKwQlEO9OA+Ox/CfWAfqEm/az0IKGkDs80 11 | 1at//i1d3ILXWJBEewHfD/q1LcqgGLQCoMTrMAUWlq2emJpZ+KQzXEp9INPJs/P8 12 | IcTMRjYzimZFRvks7YoIJyM+gRT3LnZUoBo02XZv4irRYiSJxUiNkuEUa3kCIQDh 13 | V+UuQG2G4sAlI+Ltxlb8Ge6q1MN4Vkf07AunAdOQ1QKCAgA/UnpxdSqjgkD3XvEG 14 | A3+PZ4rkQtQNNUDzBYdrOi9kAMajGpCre+FzJkktjkKoMlmQm0G5J0KMAJvAuV3R 15 | DSCVxkLkk+4PQMTKe15yCxSBJbumDS+4t7a6ce2UD69tCWXm+3rSmb9mDxBwDZHx 16 | mJgBw9s6T8ZCNmWiwUZbV1WZiCkoOkq//hqx1yWw0tcRBffNAkc0vhxuEUId92Hy 17 | gZnL+5d4a/hIRDG2ZXhKJo0xeunMuDyWwxPreAM+46OE1GYdVDD8usJ0NuiIS16j 18 | sPZc7j+Kq5zKErsV9LA1OWp68OdpJor9l+liPbfgQwnAFaJav3NadGWf5g9A3oKR 19 | cBSqyfytgkpMQjzAxhfi9NMG/I/+VfPT1urnkkMo7OJRJMNCiYKEw/TwczMYZS1C 20 | t8ZQN4HHFADa925h1GZYyTdTDzUKAI2PxsBAyLZzIYBGelMVxOjDUR9zYTZKGlOb 21 | G2reZ+jBvm4bzDQ+w0Ny4R3jnYTKPPJo/Bi0baeimiavvZpK/SIDzRekb6ZfpWBx 22 | YESDhAICiCnQQmnW5nL7487uy1tmb9rd5QCDAiTSLnYIuUGVfhKlXkm2PpjWkn8c 23 | 6qTgrci/nFch5/WZN975k7U+xttCQu5LU19TacAusOKNUgNQUq8LHccgUWKOha5M 24 | rXNuZySsWrJwdo/zyc54W8iiFAKCAgBMErTqbOns3S85yOgu26uBea7nEqrVDCnV 25 | debRcw/tR/rTj9ucnU3Y+E9Gjt55QKgIEe/ye69mrwNL/fIl4UTwvDzw7LPIlzTy 26 | N04vn1zQ3Qn/kDeMWfEBRko2ApO7m0OucE1unK7zffkx/uOPR23w2g0Oe+oMOw9w 27 | x5OLmFYoE2ZQMNIlYxYK+qXPj5O/oF4+/6waXbJJueJM/MUhkO7oZ6T4zj36YFcE 28 | 8wC2W/vuENjHcu1AYyA/L7aHf34rqw0Avc2B5KOv1+YsZWHa58iAXVGN4JcoFd0g 29 | Pr7PnYXFbJGkZuh8WVc8P+wO/+svADcPQZddGEZz4Pkkp5Dj0+3FcZYI7YeT9HyN 30 | LRmZ+7YXes8kOM+AvQiKp/5NoJefVsVNWakOLh/QwrHyG5ZzaeOb7MG/uYk7lAek 31 | 2imNj+GuWslMwX2DopXXXQ765NQ724jJ6cDAn8eH4PyjC/gcoqtiFVRsu9mwnBD9 32 | UejwlBX+qfh5B8EvxFU6cmFYgTLZRhv3xx8+nKAocyiNRm/mMMka2loa9v1d8IT+ 33 | UZa4qGOlgtiIho7wG/Wi+XH3BBes/lmQiR60vxCJI9F+o9sxJFpCiFwJdIrQXz1F 34 | d8TJ7Znb5YJNQ3HPxgk5HbQG9tMvvlPc5naN8fYhVIeuOwgoO6Isu9xcI2ZxjYye 35 | GzdLwcRfzwIhAJJWmnDRDNsnfA3QC5RnVS9K30CGPVDO3dhenkz7lX4J 36 | -----END DSA PRIVATE KEY----- 37 | -------------------------------------------------------------------------------- /packages/auto_updater/example/dsa_pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIGRjCCBDkGByqGSM44BAEwggQsAoICAQDBBSxS+JymSto7JSDQ9sr12VKxy3yN 3 | Dv4gHcxupCDJ+mL/ULYvUjSELh/jU8l5KMF2NevAzXbsOePlcLcsaB8Z9DbJjlbu 4 | YUFw1eeBaCvU0By7sqK+JeYwTGzHQ+58LosZU/2ZKjByBBx3MNYtRJL7X8YgA5ls 5 | /uLXphTSH7z0exI7F5zQrl5tO0hbO33Lv/NAj9BXqFNc/EO+nGXZirKm07iu5iaA 6 | /dRa0GHe2xtNfw55OPgHtVRJf34JqHkmLQ38sQAIzC/+jyz5yYnuyz1K8SnkbPH/ 7 | ij7N7fkUZK4baqaBlnGT3bqrfWJ6Ni9CyBUQ1yOurtd0gZB5+8NseQRR8khDr5xy 8 | PAn77jIZilFVsUR51aZQec1LTsGrZSjJRRJEmRcAd80UK6qR2lXp+SSi/x0dUtQ4 9 | 1CMPIMHonzMBiIRQ1KPR3HIvUArMndFw1tCMEKWXDBaTpDJJiIeXl9GkXBZ/7WXQ 10 | EGtLhybpQv5SC9F8JiWSxebLJ+swR8G2a+v0eOO+606+gZxNw4rBCUQ704D47H8J 11 | 9YB+oSb9rPQgoaQOzzTVq3/+LV3cgtdYkER7Ad8P+rUtyqAYtAKgxOswBRaWrZ6Y 12 | mln4pDNcSn0g08mz8/whxMxGNjOKZkVG+SztiggnIz6BFPcudlSgGjTZdm/iKtFi 13 | JInFSI2S4RRreQIhAOFX5S5AbYbiwCUj4u3GVvwZ7qrUw3hWR/TsC6cB05DVAoIC 14 | AD9SenF1KqOCQPde8QYDf49niuRC1A01QPMFh2s6L2QAxqMakKt74XMmSS2OQqgy 15 | WZCbQbknQowAm8C5XdENIJXGQuST7g9AxMp7XnILFIElu6YNL7i3trpx7ZQPr20J 16 | Zeb7etKZv2YPEHANkfGYmAHD2zpPxkI2ZaLBRltXVZmIKSg6Sr/+GrHXJbDS1xEF 17 | 980CRzS+HG4RQh33YfKBmcv7l3hr+EhEMbZleEomjTF66cy4PJbDE+t4Az7jo4TU 18 | Zh1UMPy6wnQ26IhLXqOw9lzuP4qrnMoSuxX0sDU5anrw52kmiv2X6WI9t+BDCcAV 19 | olq/c1p0ZZ/mD0DegpFwFKrJ/K2CSkxCPMDGF+L00wb8j/5V89PW6ueSQyjs4lEk 20 | w0KJgoTD9PBzMxhlLUK3xlA3gccUANr3bmHUZljJN1MPNQoAjY/GwEDItnMhgEZ6 21 | UxXE6MNRH3NhNkoaU5sbat5n6MG+bhvMND7DQ3LhHeOdhMo88mj8GLRtp6KaJq+9 22 | mkr9IgPNF6Rvpl+lYHFgRIOEAgKIKdBCadbmcvvjzu7LW2Zv2t3lAIMCJNIudgi5 23 | QZV+EqVeSbY+mNaSfxzqpOCtyL+cVyHn9Zk33vmTtT7G20JC7ktTX1NpwC6w4o1S 24 | A1BSrwsdxyBRYo6Frkytc25nJKxasnB2j/PJznhbyKIUA4ICBQACggIATBK06mzp 25 | 7N0vOcjoLturgXmu5xKq1Qwp1XXm0XMP7Uf604/bnJ1N2PhPRo7eeUCoCBHv8nuv 26 | Zq8DS/3yJeFE8Lw88OyzyJc08jdOL59c0N0J/5A3jFnxAUZKNgKTu5tDrnBNbpyu 27 | 8335Mf7jj0dt8NoNDnvqDDsPcMeTi5hWKBNmUDDSJWMWCvqlz4+Tv6BePv+sGl2y 28 | SbniTPzFIZDu6Gek+M49+mBXBPMAtlv77hDYx3LtQGMgPy+2h39+K6sNAL3NgeSj 29 | r9fmLGVh2ufIgF1RjeCXKBXdID6+z52FxWyRpGbofFlXPD/sDv/rLwA3D0GXXRhG 30 | c+D5JKeQ49PtxXGWCO2Hk/R8jS0Zmfu2F3rPJDjPgL0Iiqf+TaCXn1bFTVmpDi4f 31 | 0MKx8huWc2njm+zBv7mJO5QHpNopjY/hrlrJTMF9g6KV110O+uTUO9uIyenAwJ/H 32 | h+D8owv4HKKrYhVUbLvZsJwQ/VHo8JQV/qn4eQfBL8RVOnJhWIEy2UYb98cfPpyg 33 | KHMojUZv5jDJGtpaGvb9XfCE/lGWuKhjpYLYiIaO8Bv1ovlx9wQXrP5ZkIketL8Q 34 | iSPRfqPbMSRaQohcCXSK0F89RXfEye2Z2+WCTUNxz8YJOR20BvbTL75T3OZ2jfH2 35 | IVSHrjsIKDuiLLvcXCNmcY2Mnhs3S8HEX88= 36 | -----END PUBLIC KEY----- 37 | -------------------------------------------------------------------------------- /packages/auto_updater/example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_updater_example/pages/home.dart'; 2 | import 'package:bot_toast/bot_toast.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:window_manager/window_manager.dart'; 5 | 6 | void main() async { 7 | WidgetsFlutterBinding.ensureInitialized(); 8 | await windowManager.ensureInitialized(); 9 | 10 | windowManager.waitUntilReadyToShow(null, () async { 11 | await windowManager.setPreventClose(true); 12 | await windowManager.show(); 13 | await windowManager.focus(); 14 | }); 15 | 16 | runApp(const MyApp()); 17 | } 18 | 19 | class MyApp extends StatefulWidget { 20 | const MyApp({super.key}); 21 | 22 | @override 23 | State createState() => _MyAppState(); 24 | } 25 | 26 | class _MyAppState extends State { 27 | @override 28 | Widget build(BuildContext context) { 29 | return MaterialApp( 30 | theme: ThemeData( 31 | primaryColor: const Color(0xff416ff4), 32 | canvasColor: Colors.white, 33 | scaffoldBackgroundColor: const Color(0xffF7F9FB), 34 | dividerColor: Colors.grey.withOpacity(0.3), 35 | ), 36 | builder: BotToastInit(), 37 | navigatorObservers: [BotToastNavigatorObserver()], 38 | home: const HomePage(), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/auto_updater/example/lib/pages/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_updater/auto_updater.dart'; 2 | import 'package:bot_toast/bot_toast.dart'; 3 | import 'package:flutter/foundation.dart'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:window_manager/window_manager.dart'; 6 | 7 | class HomePage extends StatefulWidget { 8 | const HomePage({super.key}); 9 | 10 | @override 11 | State createState() => _HomePageState(); 12 | } 13 | 14 | class _HomePageState extends State with UpdaterListener { 15 | final String _feedURL = 'http://localhost:5002/appcast.xml'; 16 | 17 | bool _isFeedURLSetted = false; 18 | 19 | @override 20 | void initState() { 21 | autoUpdater.addListener(this); 22 | super.initState(); 23 | } 24 | 25 | @override 26 | void dispose() { 27 | autoUpdater.removeListener(this); 28 | super.dispose(); 29 | } 30 | 31 | Future _handleClickSetFeedURL() async { 32 | await autoUpdater.setFeedURL(_feedURL); 33 | _isFeedURLSetted = true; 34 | } 35 | 36 | Future _handleClickCheckForUpdates() async { 37 | if (!_isFeedURLSetted) { 38 | BotToast.showText(text: 'Please call setFeedURL method first.'); 39 | return; 40 | } 41 | await autoUpdater.checkForUpdates(); 42 | } 43 | 44 | Future _handleClickCheckForUpdatesWithoutUI() async { 45 | await autoUpdater.checkForUpdates(inBackground: true); 46 | } 47 | 48 | Future _handleClickSetScheduledCheckInterval() async { 49 | await autoUpdater.setScheduledCheckInterval(3600); 50 | } 51 | 52 | Widget _buildBody(BuildContext context) { 53 | return ListView( 54 | children: [ 55 | Column( 56 | // title: const Text('METHODS'), 57 | children: [ 58 | ListTile( 59 | title: const Text('setFeedURL'), 60 | trailing: Text(_feedURL), 61 | onTap: () { 62 | _handleClickSetFeedURL(); 63 | }, 64 | ), 65 | ListTile( 66 | title: const Text('checkForUpdates'), 67 | onTap: () { 68 | _handleClickCheckForUpdates(); 69 | }, 70 | ), 71 | ListTile( 72 | title: const Text('checkForUpdatesWithoutUI'), 73 | onTap: () { 74 | _handleClickCheckForUpdatesWithoutUI(); 75 | }, 76 | ), 77 | ListTile( 78 | title: const Text('setScheduledCheckInterval'), 79 | onTap: () { 80 | _handleClickSetScheduledCheckInterval(); 81 | }, 82 | ), 83 | ], 84 | ), 85 | ], 86 | ); 87 | } 88 | 89 | @override 90 | Widget build(BuildContext context) { 91 | return Scaffold( 92 | appBar: AppBar( 93 | title: const Text('Plugin example app'), 94 | ), 95 | body: _buildBody(context), 96 | ); 97 | } 98 | 99 | @override 100 | void onUpdaterError(UpdaterError? error) { 101 | if (kDebugMode) { 102 | print('onUpdaterError: $error'); 103 | } 104 | } 105 | 106 | @override 107 | void onUpdaterCheckingForUpdate(Appcast? appcast) { 108 | if (kDebugMode) { 109 | print('onUpdaterCheckingForUpdate: ${appcast?.toJson()}'); 110 | } 111 | } 112 | 113 | @override 114 | void onUpdaterUpdateAvailable(AppcastItem? item) { 115 | if (kDebugMode) { 116 | print('onUpdaterUpdateAvailable: ${item?.toJson()}'); 117 | } 118 | } 119 | 120 | @override 121 | void onUpdaterUpdateNotAvailable(UpdaterError? error) { 122 | if (kDebugMode) { 123 | print('onUpdaterUpdateNotAvailable: $error'); 124 | } 125 | } 126 | 127 | @override 128 | void onUpdaterUpdateDownloaded(AppcastItem? item) { 129 | if (kDebugMode) { 130 | print('onUpdaterUpdateDownloaded: ${item?.toJson()}'); 131 | } 132 | } 133 | 134 | @override 135 | void onUpdaterBeforeQuitForUpdate(AppcastItem? item) { 136 | if (kDebugMode) { 137 | print('onUpdaterBeforeQuitForUpdate: ${item?.toJson()}'); 138 | } 139 | windowManager.setPreventClose(false); 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import auto_updater_macos 9 | import screen_retriever_macos 10 | import window_manager 11 | 12 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 13 | AutoUpdaterMacosPlugin.register(with: registry.registrar(forPlugin: "AutoUpdaterMacosPlugin")) 14 | ScreenRetrieverMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenRetrieverMacosPlugin")) 15 | WindowManagerPlugin.register(with: registry.registrar(forPlugin: "WindowManagerPlugin")) 16 | } 17 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.14' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | end 35 | 36 | post_install do |installer| 37 | installer.pods_project.targets.each do |target| 38 | flutter_additional_macos_build_settings(target) 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - auto_updater_macos (0.0.1): 3 | - FlutterMacOS 4 | - Sparkle 5 | - FlutterMacOS (1.0.0) 6 | - screen_retriever_macos (0.0.1): 7 | - FlutterMacOS 8 | - Sparkle (2.5.2) 9 | - window_manager (0.2.0): 10 | - FlutterMacOS 11 | 12 | DEPENDENCIES: 13 | - auto_updater_macos (from `Flutter/ephemeral/.symlinks/plugins/auto_updater_macos/macos`) 14 | - FlutterMacOS (from `Flutter/ephemeral`) 15 | - screen_retriever_macos (from `Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos`) 16 | - window_manager (from `Flutter/ephemeral/.symlinks/plugins/window_manager/macos`) 17 | 18 | SPEC REPOS: 19 | trunk: 20 | - Sparkle 21 | 22 | EXTERNAL SOURCES: 23 | auto_updater_macos: 24 | :path: Flutter/ephemeral/.symlinks/plugins/auto_updater_macos/macos 25 | FlutterMacOS: 26 | :path: Flutter/ephemeral 27 | screen_retriever_macos: 28 | :path: Flutter/ephemeral/.symlinks/plugins/screen_retriever_macos/macos 29 | window_manager: 30 | :path: Flutter/ephemeral/.symlinks/plugins/window_manager/macos 31 | 32 | SPEC CHECKSUMS: 33 | auto_updater_macos: 3e3462c418fe4e731917eacd8d28eef7af84086d 34 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 35 | screen_retriever_macos: 776e0fa5d42c6163d2bf772d22478df4b302b161 36 | Sparkle: 0e335e5c704ac28dbea18cc0383e15a3927c28dc 37 | window_manager: 3a1844359a6295ab1e47659b1a777e36773cd6e8 38 | 39 | PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 40 | 41 | COCOAPODS: 1.14.3 42 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @main 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = auto_updater_example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = org.leanflutter.plugins.autoUpdaterExample 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2022 org.leanflutter.plugins. All rights reserved. 15 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.client 10 | 11 | com.apple.security.network.server 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | NSAppTransportSecurity 20 | 21 | NSAllowsArbitraryLoads 22 | 23 | 24 | CFBundleShortVersionString 25 | $(FLUTTER_BUILD_NAME) 26 | CFBundleVersion 27 | $(FLUTTER_BUILD_NUMBER) 28 | LSMinimumSystemVersion 29 | $(MACOSX_DEPLOYMENT_TARGET) 30 | NSHumanReadableCopyright 31 | $(PRODUCT_COPYRIGHT) 32 | NSMainNibFile 33 | MainMenu 34 | NSPrincipalClass 35 | NSApplication 36 | SUPublicEDKey 37 | frAJxov3qLUBA7EbVq0yhs8EKGPlRE/V2tTP1Ao6J7M= 38 | 39 | 40 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController.init() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.network.client 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /packages/auto_updater/example/macos/packaging/dmg/make_config.yaml: -------------------------------------------------------------------------------- 1 | title: auto_updater_example 2 | contents: 3 | - x: 448 4 | y: 344 5 | type: link 6 | path: "/Applications" 7 | - x: 192 8 | y: 344 9 | type: file 10 | path: auto_updater_example.app 11 | -------------------------------------------------------------------------------- /packages/auto_updater/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater_example 2 | description: Demonstrates how to use the auto_updater plugin. 3 | version: 1.0.0+1 4 | publish_to: "none" 5 | 6 | environment: 7 | sdk: ">=3.0.0 <4.0.0" 8 | 9 | dependencies: 10 | auto_updater: 11 | path: ../ 12 | bot_toast: ^4.1.3 13 | flutter: 14 | sdk: flutter 15 | window_manager: ^0.4.3 16 | 17 | dev_dependencies: 18 | flutter_test: 19 | sdk: flutter 20 | mostly_reasonable_lints: ^0.1.2 21 | 22 | flutter: 23 | uses-material-design: true 24 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project-level configuration. 2 | cmake_minimum_required(VERSION 3.14) 3 | project(auto_updater_example LANGUAGES CXX) 4 | 5 | # The name of the executable created for the application. Change this to change 6 | # the on-disk name of your application. 7 | set(BINARY_NAME "auto_updater_example") 8 | 9 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent 10 | # versions of CMake. 11 | cmake_policy(SET CMP0063 NEW) 12 | 13 | # Define build configuration option. 14 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 15 | if(IS_MULTICONFIG) 16 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" 17 | CACHE STRING "" FORCE) 18 | else() 19 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 20 | set(CMAKE_BUILD_TYPE "Debug" CACHE 21 | STRING "Flutter build mode" FORCE) 22 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 23 | "Debug" "Profile" "Release") 24 | endif() 25 | endif() 26 | # Define settings for the Profile build mode. 27 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") 28 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") 29 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") 30 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") 31 | 32 | # Use Unicode for all projects. 33 | add_definitions(-DUNICODE -D_UNICODE) 34 | 35 | # Compilation settings that should be applied to most targets. 36 | # 37 | # Be cautious about adding new options here, as plugins use this function by 38 | # default. In most cases, you should add new options to specific targets instead 39 | # of modifying this function. 40 | function(APPLY_STANDARD_SETTINGS TARGET) 41 | target_compile_features(${TARGET} PUBLIC cxx_std_17) 42 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") 43 | target_compile_options(${TARGET} PRIVATE /EHsc) 44 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") 45 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") 46 | endfunction() 47 | 48 | # Flutter library and tool build rules. 49 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 50 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 51 | 52 | # Application build; see runner/CMakeLists.txt. 53 | add_subdirectory("runner") 54 | 55 | 56 | # Generated plugin build rules, which manage building the plugins and adding 57 | # them to the application. 58 | include(flutter/generated_plugins.cmake) 59 | 60 | 61 | # === Installation === 62 | # Support files are copied into place next to the executable, so that it can 63 | # run in place. This is done instead of making a separate bundle (as on Linux) 64 | # so that building and running from within Visual Studio will work. 65 | set(BUILD_BUNDLE_DIR "$") 66 | # Make the "install" step default, as it's required to run. 67 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) 68 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 69 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 70 | endif() 71 | 72 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 73 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 74 | 75 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 76 | COMPONENT Runtime) 77 | 78 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 79 | COMPONENT Runtime) 80 | 81 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 82 | COMPONENT Runtime) 83 | 84 | if(PLUGIN_BUNDLED_LIBRARIES) 85 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 86 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 87 | COMPONENT Runtime) 88 | endif() 89 | 90 | # Fully re-copy the assets directory on each build to avoid having stale files 91 | # from a previous install. 92 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 93 | install(CODE " 94 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 95 | " COMPONENT Runtime) 96 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 97 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 98 | 99 | # Install the AOT library on non-Debug builds only. 100 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 101 | CONFIGURATIONS Profile;Release 102 | COMPONENT Runtime) 103 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.14) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 12 | 13 | # Set fallback configurations for older versions of the flutter tool. 14 | if (NOT DEFINED FLUTTER_TARGET_PLATFORM) 15 | set(FLUTTER_TARGET_PLATFORM "windows-x64") 16 | endif() 17 | 18 | # === Flutter Library === 19 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 20 | 21 | # Published to parent scope for install step. 22 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 23 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 24 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 25 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 26 | 27 | list(APPEND FLUTTER_LIBRARY_HEADERS 28 | "flutter_export.h" 29 | "flutter_windows.h" 30 | "flutter_messenger.h" 31 | "flutter_plugin_registrar.h" 32 | "flutter_texture_registrar.h" 33 | ) 34 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 35 | add_library(flutter INTERFACE) 36 | target_include_directories(flutter INTERFACE 37 | "${EPHEMERAL_DIR}" 38 | ) 39 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 40 | add_dependencies(flutter flutter_assemble) 41 | 42 | # === Wrapper === 43 | list(APPEND CPP_WRAPPER_SOURCES_CORE 44 | "core_implementations.cc" 45 | "standard_codec.cc" 46 | ) 47 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 48 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 49 | "plugin_registrar.cc" 50 | ) 51 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 52 | list(APPEND CPP_WRAPPER_SOURCES_APP 53 | "flutter_engine.cc" 54 | "flutter_view_controller.cc" 55 | ) 56 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 57 | 58 | # Wrapper sources needed for a plugin. 59 | add_library(flutter_wrapper_plugin STATIC 60 | ${CPP_WRAPPER_SOURCES_CORE} 61 | ${CPP_WRAPPER_SOURCES_PLUGIN} 62 | ) 63 | apply_standard_settings(flutter_wrapper_plugin) 64 | set_target_properties(flutter_wrapper_plugin PROPERTIES 65 | POSITION_INDEPENDENT_CODE ON) 66 | set_target_properties(flutter_wrapper_plugin PROPERTIES 67 | CXX_VISIBILITY_PRESET hidden) 68 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 69 | target_include_directories(flutter_wrapper_plugin PUBLIC 70 | "${WRAPPER_ROOT}/include" 71 | ) 72 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 73 | 74 | # Wrapper sources needed for the runner. 75 | add_library(flutter_wrapper_app STATIC 76 | ${CPP_WRAPPER_SOURCES_CORE} 77 | ${CPP_WRAPPER_SOURCES_APP} 78 | ) 79 | apply_standard_settings(flutter_wrapper_app) 80 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 81 | target_include_directories(flutter_wrapper_app PUBLIC 82 | "${WRAPPER_ROOT}/include" 83 | ) 84 | add_dependencies(flutter_wrapper_app flutter_assemble) 85 | 86 | # === Flutter tool backend === 87 | # _phony_ is a non-existent file to force this command to run every time, 88 | # since currently there's no way to get a full input/output list from the 89 | # flutter tool. 90 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") 91 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) 92 | add_custom_command( 93 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 94 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 95 | ${CPP_WRAPPER_SOURCES_APP} 96 | ${PHONY_OUTPUT} 97 | COMMAND ${CMAKE_COMMAND} -E env 98 | ${FLUTTER_TOOL_ENVIRONMENT} 99 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 100 | ${FLUTTER_TARGET_PLATFORM} $ 101 | VERBATIM 102 | ) 103 | add_custom_target(flutter_assemble DEPENDS 104 | "${FLUTTER_LIBRARY}" 105 | ${FLUTTER_LIBRARY_HEADERS} 106 | ${CPP_WRAPPER_SOURCES_CORE} 107 | ${CPP_WRAPPER_SOURCES_PLUGIN} 108 | ${CPP_WRAPPER_SOURCES_APP} 109 | ) 110 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | void RegisterPlugins(flutter::PluginRegistry* registry) { 14 | AutoUpdaterWindowsPluginCApiRegisterWithRegistrar( 15 | registry->GetRegistrarForPlugin("AutoUpdaterWindowsPluginCApi")); 16 | ScreenRetrieverPluginRegisterWithRegistrar( 17 | registry->GetRegistrarForPlugin("ScreenRetrieverPlugin")); 18 | WindowManagerPluginRegisterWithRegistrar( 19 | registry->GetRegistrarForPlugin("WindowManagerPlugin")); 20 | } 21 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | auto_updater_windows 7 | screen_retriever 8 | window_manager 9 | ) 10 | 11 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 12 | ) 13 | 14 | set(PLUGIN_BUNDLED_LIBRARIES) 15 | 16 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 17 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 18 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 20 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 21 | endforeach(plugin) 22 | 23 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 24 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 25 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 26 | endforeach(ffi_plugin) 27 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/packaging/exe/make_config.yaml: -------------------------------------------------------------------------------- 1 | app_id: 1D7A5470-942F-4649-8B69-122888AB0BA5 2 | display_name: auto_updater_example 3 | publisher: LeanFlutter 4 | publisher_url: https://github.com/leanflutter/auto_updater 5 | locales: 6 | - en 7 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Add preprocessor definitions for the build version. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") 25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") 26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") 27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") 28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") 29 | 30 | # Disable Windows macros that collide with C++ standard library functions. 31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 32 | 33 | # Add dependency libraries and include directories. Add any application-specific 34 | # dependencies here. 35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 36 | target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") 37 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 38 | 39 | # Run the Flutter tool portions of the build. This must not be removed. 40 | add_dependencies(${BINARY_NAME} flutter_assemble) 41 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) 64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0,0 67 | #endif 68 | 69 | #if defined(FLUTTER_VERSION) 70 | #define VERSION_AS_STRING FLUTTER_VERSION 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.example" "\0" 93 | VALUE "FileDescription", "auto_updater_example" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "auto_updater_example" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2023 com.example. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "auto_updater_example.exe" "\0" 98 | VALUE "ProductName", "auto_updater_example" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | 123 | 124 | ///////////////////////////////////////////////////////////////////////////// 125 | // 126 | // WinSparkle 127 | // 128 | 129 | // And verify signature using DSA public key: 130 | DSAPub DSAPEM "../../dsa_pub.pem" 131 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | 30 | flutter_controller_->engine()->SetNextFrameCallback([&]() { 31 | this->Show(); 32 | }); 33 | 34 | // Flutter can complete the first frame before the "show window" callback is 35 | // registered. The following call ensures a frame is pending to ensure the 36 | // window is shown. It is a no-op if the first frame hasn't completed yet. 37 | flutter_controller_->ForceRedraw(); 38 | 39 | return true; 40 | } 41 | 42 | void FlutterWindow::OnDestroy() { 43 | if (flutter_controller_) { 44 | flutter_controller_ = nullptr; 45 | } 46 | 47 | Win32Window::OnDestroy(); 48 | } 49 | 50 | LRESULT 51 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 52 | WPARAM const wparam, 53 | LPARAM const lparam) noexcept { 54 | // Give Flutter, including plugins, an opportunity to handle window messages. 55 | if (flutter_controller_) { 56 | std::optional result = 57 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 58 | lparam); 59 | if (result) { 60 | return *result; 61 | } 62 | } 63 | 64 | switch (message) { 65 | case WM_FONTCHANGE: 66 | flutter_controller_->engine()->ReloadSystemFonts(); 67 | break; 68 | } 69 | 70 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 71 | } 72 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"auto_updater_example"); 11 | if (hwnd != NULL) { 12 | ::ShowWindow(hwnd, SW_NORMAL); 13 | ::SetForegroundWindow(hwnd); 14 | return EXIT_FAILURE; 15 | } 16 | // Attach to console when present (e.g., 'flutter run') or create a 17 | // new console when running with a debugger. 18 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 19 | CreateAndAttachConsole(); 20 | } 21 | 22 | // Initialize COM, so that it is available for use in the library and/or 23 | // plugins. 24 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 25 | 26 | flutter::DartProject project(L"data"); 27 | 28 | std::vector command_line_arguments = 29 | GetCommandLineArguments(); 30 | 31 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 32 | 33 | FlutterWindow window(project); 34 | Win32Window::Point origin(10, 10); 35 | Win32Window::Size size(1280, 720); 36 | if (!window.Create(L"auto_updater_example", origin, size)) { 37 | return EXIT_FAILURE; 38 | } 39 | window.SetQuitOnClose(true); 40 | 41 | ::MSG msg; 42 | while (::GetMessage(&msg, nullptr, 0, 0)) { 43 | ::TranslateMessage(&msg); 44 | ::DispatchMessage(&msg); 45 | } 46 | 47 | ::CoUninitialize(); 48 | return EXIT_SUCCESS; 49 | } 50 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr) 51 | -1; // remove the trailing null character 52 | int input_length = (int)wcslen(utf16_string); 53 | std::string utf8_string; 54 | if (target_length <= 0 || target_length > utf8_string.max_size()) { 55 | return utf8_string; 56 | } 57 | utf8_string.resize(target_length); 58 | int converted_length = ::WideCharToMultiByte( 59 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 60 | input_length, utf8_string.data(), target_length, nullptr, nullptr); 61 | if (converted_length == 0) { 62 | return std::string(); 63 | } 64 | return utf8_string; 65 | } 66 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/win32_window.cpp: -------------------------------------------------------------------------------- 1 | #include "win32_window.h" 2 | 3 | #include 4 | #include 5 | 6 | #include "resource.h" 7 | 8 | namespace { 9 | 10 | /// Window attribute that enables dark mode window decorations. 11 | /// 12 | /// Redefined in case the developer's machine has a Windows SDK older than 13 | /// version 10.0.22000.0. 14 | /// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute 15 | #ifndef DWMWA_USE_IMMERSIVE_DARK_MODE 16 | #define DWMWA_USE_IMMERSIVE_DARK_MODE 20 17 | #endif 18 | 19 | constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; 20 | 21 | /// Registry key for app theme preference. 22 | /// 23 | /// A value of 0 indicates apps should use dark mode. A non-zero or missing 24 | /// value indicates apps should use light mode. 25 | constexpr const wchar_t kGetPreferredBrightnessRegKey[] = 26 | L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize"; 27 | constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme"; 28 | 29 | // The number of Win32Window objects that currently exist. 30 | static int g_active_window_count = 0; 31 | 32 | using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); 33 | 34 | // Scale helper to convert logical scaler values to physical using passed in 35 | // scale factor 36 | int Scale(int source, double scale_factor) { 37 | return static_cast(source * scale_factor); 38 | } 39 | 40 | // Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. 41 | // This API is only needed for PerMonitor V1 awareness mode. 42 | void EnableFullDpiSupportIfAvailable(HWND hwnd) { 43 | HMODULE user32_module = LoadLibraryA("User32.dll"); 44 | if (!user32_module) { 45 | return; 46 | } 47 | auto enable_non_client_dpi_scaling = 48 | reinterpret_cast( 49 | GetProcAddress(user32_module, "EnableNonClientDpiScaling")); 50 | if (enable_non_client_dpi_scaling != nullptr) { 51 | enable_non_client_dpi_scaling(hwnd); 52 | } 53 | FreeLibrary(user32_module); 54 | } 55 | 56 | } // namespace 57 | 58 | // Manages the Win32Window's window class registration. 59 | class WindowClassRegistrar { 60 | public: 61 | ~WindowClassRegistrar() = default; 62 | 63 | // Returns the singleton registrar instance. 64 | static WindowClassRegistrar* GetInstance() { 65 | if (!instance_) { 66 | instance_ = new WindowClassRegistrar(); 67 | } 68 | return instance_; 69 | } 70 | 71 | // Returns the name of the window class, registering the class if it hasn't 72 | // previously been registered. 73 | const wchar_t* GetWindowClass(); 74 | 75 | // Unregisters the window class. Should only be called if there are no 76 | // instances of the window. 77 | void UnregisterWindowClass(); 78 | 79 | private: 80 | WindowClassRegistrar() = default; 81 | 82 | static WindowClassRegistrar* instance_; 83 | 84 | bool class_registered_ = false; 85 | }; 86 | 87 | WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; 88 | 89 | const wchar_t* WindowClassRegistrar::GetWindowClass() { 90 | if (!class_registered_) { 91 | WNDCLASS window_class{}; 92 | window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); 93 | window_class.lpszClassName = kWindowClassName; 94 | window_class.style = CS_HREDRAW | CS_VREDRAW; 95 | window_class.cbClsExtra = 0; 96 | window_class.cbWndExtra = 0; 97 | window_class.hInstance = GetModuleHandle(nullptr); 98 | window_class.hIcon = 99 | LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); 100 | window_class.hbrBackground = 0; 101 | window_class.lpszMenuName = nullptr; 102 | window_class.lpfnWndProc = Win32Window::WndProc; 103 | RegisterClass(&window_class); 104 | class_registered_ = true; 105 | } 106 | return kWindowClassName; 107 | } 108 | 109 | void WindowClassRegistrar::UnregisterWindowClass() { 110 | UnregisterClass(kWindowClassName, nullptr); 111 | class_registered_ = false; 112 | } 113 | 114 | Win32Window::Win32Window() { 115 | ++g_active_window_count; 116 | } 117 | 118 | Win32Window::~Win32Window() { 119 | --g_active_window_count; 120 | Destroy(); 121 | } 122 | 123 | bool Win32Window::Create(const std::wstring& title, 124 | const Point& origin, 125 | const Size& size) { 126 | Destroy(); 127 | 128 | const wchar_t* window_class = 129 | WindowClassRegistrar::GetInstance()->GetWindowClass(); 130 | 131 | const POINT target_point = {static_cast(origin.x), 132 | static_cast(origin.y)}; 133 | HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); 134 | UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); 135 | double scale_factor = dpi / 96.0; 136 | 137 | HWND window = CreateWindow( 138 | window_class, title.c_str(), WS_OVERLAPPEDWINDOW, 139 | Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), 140 | Scale(size.width, scale_factor), Scale(size.height, scale_factor), 141 | nullptr, nullptr, GetModuleHandle(nullptr), this); 142 | 143 | if (!window) { 144 | return false; 145 | } 146 | 147 | UpdateTheme(window); 148 | 149 | return OnCreate(); 150 | } 151 | 152 | bool Win32Window::Show() { 153 | return ShowWindow(window_handle_, SW_SHOWNORMAL); 154 | } 155 | 156 | // static 157 | LRESULT CALLBACK Win32Window::WndProc(HWND const window, 158 | UINT const message, 159 | WPARAM const wparam, 160 | LPARAM const lparam) noexcept { 161 | if (message == WM_NCCREATE) { 162 | auto window_struct = reinterpret_cast(lparam); 163 | SetWindowLongPtr(window, GWLP_USERDATA, 164 | reinterpret_cast(window_struct->lpCreateParams)); 165 | 166 | auto that = static_cast(window_struct->lpCreateParams); 167 | EnableFullDpiSupportIfAvailable(window); 168 | that->window_handle_ = window; 169 | } else if (Win32Window* that = GetThisFromHandle(window)) { 170 | return that->MessageHandler(window, message, wparam, lparam); 171 | } 172 | 173 | return DefWindowProc(window, message, wparam, lparam); 174 | } 175 | 176 | LRESULT 177 | Win32Window::MessageHandler(HWND hwnd, 178 | UINT const message, 179 | WPARAM const wparam, 180 | LPARAM const lparam) noexcept { 181 | switch (message) { 182 | case WM_DESTROY: 183 | window_handle_ = nullptr; 184 | Destroy(); 185 | if (quit_on_close_) { 186 | PostQuitMessage(0); 187 | } 188 | return 0; 189 | 190 | case WM_DPICHANGED: { 191 | auto newRectSize = reinterpret_cast(lparam); 192 | LONG newWidth = newRectSize->right - newRectSize->left; 193 | LONG newHeight = newRectSize->bottom - newRectSize->top; 194 | 195 | SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, 196 | newHeight, SWP_NOZORDER | SWP_NOACTIVATE); 197 | 198 | return 0; 199 | } 200 | case WM_SIZE: { 201 | RECT rect = GetClientArea(); 202 | if (child_content_ != nullptr) { 203 | // Size and position the child window. 204 | MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, 205 | rect.bottom - rect.top, TRUE); 206 | } 207 | return 0; 208 | } 209 | 210 | case WM_ACTIVATE: 211 | if (child_content_ != nullptr) { 212 | SetFocus(child_content_); 213 | } 214 | return 0; 215 | 216 | case WM_DWMCOLORIZATIONCOLORCHANGED: 217 | UpdateTheme(hwnd); 218 | return 0; 219 | } 220 | 221 | return DefWindowProc(window_handle_, message, wparam, lparam); 222 | } 223 | 224 | void Win32Window::Destroy() { 225 | OnDestroy(); 226 | 227 | if (window_handle_) { 228 | DestroyWindow(window_handle_); 229 | window_handle_ = nullptr; 230 | } 231 | if (g_active_window_count == 0) { 232 | WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); 233 | } 234 | } 235 | 236 | Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { 237 | return reinterpret_cast( 238 | GetWindowLongPtr(window, GWLP_USERDATA)); 239 | } 240 | 241 | void Win32Window::SetChildContent(HWND content) { 242 | child_content_ = content; 243 | SetParent(content, window_handle_); 244 | RECT frame = GetClientArea(); 245 | 246 | MoveWindow(content, frame.left, frame.top, frame.right - frame.left, 247 | frame.bottom - frame.top, true); 248 | 249 | SetFocus(child_content_); 250 | } 251 | 252 | RECT Win32Window::GetClientArea() { 253 | RECT frame; 254 | GetClientRect(window_handle_, &frame); 255 | return frame; 256 | } 257 | 258 | HWND Win32Window::GetHandle() { 259 | return window_handle_; 260 | } 261 | 262 | void Win32Window::SetQuitOnClose(bool quit_on_close) { 263 | quit_on_close_ = quit_on_close; 264 | } 265 | 266 | bool Win32Window::OnCreate() { 267 | // No-op; provided for subclasses. 268 | return true; 269 | } 270 | 271 | void Win32Window::OnDestroy() { 272 | // No-op; provided for subclasses. 273 | } 274 | 275 | void Win32Window::UpdateTheme(HWND const window) { 276 | DWORD light_mode; 277 | DWORD light_mode_size = sizeof(light_mode); 278 | LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey, 279 | kGetPreferredBrightnessRegValue, 280 | RRF_RT_REG_DWORD, nullptr, &light_mode, 281 | &light_mode_size); 282 | 283 | if (result == ERROR_SUCCESS) { 284 | BOOL enable_dark_mode = light_mode == 0; 285 | DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE, 286 | &enable_dark_mode, sizeof(enable_dark_mode)); 287 | } 288 | } 289 | -------------------------------------------------------------------------------- /packages/auto_updater/example/windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_WIN32_WINDOW_H_ 2 | #define RUNNER_WIN32_WINDOW_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 11 | // inherited from by classes that wish to specialize with custom 12 | // rendering and input handling 13 | class Win32Window { 14 | public: 15 | struct Point { 16 | unsigned int x; 17 | unsigned int y; 18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 19 | }; 20 | 21 | struct Size { 22 | unsigned int width; 23 | unsigned int height; 24 | Size(unsigned int width, unsigned int height) 25 | : width(width), height(height) {} 26 | }; 27 | 28 | Win32Window(); 29 | virtual ~Win32Window(); 30 | 31 | // Creates a win32 window with |title| that is positioned and sized using 32 | // |origin| and |size|. New windows are created on the default monitor. Window 33 | // sizes are specified to the OS in physical pixels, hence to ensure a 34 | // consistent size this function will scale the inputted width and height as 35 | // as appropriate for the default monitor. The window is invisible until 36 | // |Show| is called. Returns true if the window was created successfully. 37 | bool Create(const std::wstring& title, const Point& origin, const Size& size); 38 | 39 | // Show the current window. Returns true if the window was successfully shown. 40 | bool Show(); 41 | 42 | // Release OS resources associated with window. 43 | void Destroy(); 44 | 45 | // Inserts |content| into the window tree. 46 | void SetChildContent(HWND content); 47 | 48 | // Returns the backing Window handle to enable clients to set icon and other 49 | // window properties. Returns nullptr if the window has been destroyed. 50 | HWND GetHandle(); 51 | 52 | // If true, closing this window will quit the application. 53 | void SetQuitOnClose(bool quit_on_close); 54 | 55 | // Return a RECT representing the bounds of the current client area. 56 | RECT GetClientArea(); 57 | 58 | protected: 59 | // Processes and route salient window messages for mouse handling, 60 | // size change and DPI. Delegates handling of these to member overloads that 61 | // inheriting classes can handle. 62 | virtual LRESULT MessageHandler(HWND window, 63 | UINT const message, 64 | WPARAM const wparam, 65 | LPARAM const lparam) noexcept; 66 | 67 | // Called when CreateAndShow is called, allowing subclass window-related 68 | // setup. Subclasses should return false if setup fails. 69 | virtual bool OnCreate(); 70 | 71 | // Called when Destroy is called. 72 | virtual void OnDestroy(); 73 | 74 | private: 75 | friend class WindowClassRegistrar; 76 | 77 | // OS callback called by message pump. Handles the WM_NCCREATE message which 78 | // is passed when the non-client area is being created and enables automatic 79 | // non-client DPI scaling so that the non-client area automatically 80 | // responds to changes in DPI. All other messages are handled by 81 | // MessageHandler. 82 | static LRESULT CALLBACK WndProc(HWND const window, 83 | UINT const message, 84 | WPARAM const wparam, 85 | LPARAM const lparam) noexcept; 86 | 87 | // Retrieves a class instance pointer for |window| 88 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 89 | 90 | // Update the window frame's theme to match the system theme. 91 | static void UpdateTheme(HWND const window); 92 | 93 | bool quit_on_close_ = false; 94 | 95 | // window handle for top level window. 96 | HWND window_handle_ = nullptr; 97 | 98 | // window handle for hosted content. 99 | HWND child_content_ = nullptr; 100 | }; 101 | 102 | #endif // RUNNER_WIN32_WINDOW_H_ 103 | -------------------------------------------------------------------------------- /packages/auto_updater/lib/auto_updater.dart: -------------------------------------------------------------------------------- 1 | library auto_updater; 2 | 3 | export 'src/appcast.dart'; 4 | export 'src/auto_updater.dart'; 5 | export 'src/updater_error.dart'; 6 | export 'src/updater_listener.dart'; 7 | -------------------------------------------------------------------------------- /packages/auto_updater/lib/src/appcast.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'appcast.g.dart'; 4 | 5 | @JsonSerializable() 6 | class Appcast { 7 | const Appcast({ 8 | required this.items, 9 | }); 10 | 11 | factory Appcast.fromJson(Map json) { 12 | json['items'] = (json['items'] as List) 13 | .map((e) => (e as Map).cast()) 14 | .toList(); 15 | return _$AppcastFromJson(json); 16 | } 17 | 18 | final List items; 19 | 20 | Map toJson() => _$AppcastToJson(this); 21 | } 22 | 23 | @JsonSerializable() 24 | class AppcastItem { 25 | const AppcastItem({ 26 | this.versionString, 27 | this.displayVersionString, 28 | this.fileURL, 29 | this.contentLength, 30 | this.infoURL, 31 | this.title, 32 | this.dateString, 33 | this.releaseNotesURL, 34 | this.itemDescription, 35 | this.itemDescriptionFormat, 36 | this.fullReleaseNotesURL, 37 | this.minimumSystemVersion, 38 | this.minimumOperatingSystemVersionIsOK, 39 | this.maximumSystemVersion, 40 | this.maximumOperatingSystemVersionIsOK, 41 | this.channel, 42 | }); 43 | 44 | factory AppcastItem.fromJson(Map json) => 45 | _$AppcastItemFromJson(json); 46 | 47 | final String? versionString; 48 | final String? displayVersionString; 49 | final String? fileURL; 50 | final int? contentLength; 51 | final String? infoURL; 52 | final String? title; 53 | final String? dateString; 54 | final String? releaseNotesURL; 55 | final String? itemDescription; 56 | final String? itemDescriptionFormat; 57 | final String? fullReleaseNotesURL; 58 | final String? minimumSystemVersion; 59 | final bool? minimumOperatingSystemVersionIsOK; 60 | final String? maximumSystemVersion; 61 | final bool? maximumOperatingSystemVersionIsOK; 62 | final String? channel; 63 | 64 | Map toJson() => _$AppcastItemToJson(this); 65 | } 66 | -------------------------------------------------------------------------------- /packages/auto_updater/lib/src/appcast.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'appcast.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Appcast _$AppcastFromJson(Map json) => Appcast( 10 | items: (json['items'] as List) 11 | .map((e) => AppcastItem.fromJson(e as Map)) 12 | .toList(), 13 | ); 14 | 15 | Map _$AppcastToJson(Appcast instance) => { 16 | 'items': instance.items, 17 | }; 18 | 19 | AppcastItem _$AppcastItemFromJson(Map json) => AppcastItem( 20 | versionString: json['versionString'] as String?, 21 | displayVersionString: json['displayVersionString'] as String?, 22 | fileURL: json['fileURL'] as String?, 23 | contentLength: json['contentLength'] as int?, 24 | infoURL: json['infoURL'] as String?, 25 | title: json['title'] as String?, 26 | dateString: json['dateString'] as String?, 27 | releaseNotesURL: json['releaseNotesURL'] as String?, 28 | itemDescription: json['itemDescription'] as String?, 29 | itemDescriptionFormat: json['itemDescriptionFormat'] as String?, 30 | fullReleaseNotesURL: json['fullReleaseNotesURL'] as String?, 31 | minimumSystemVersion: json['minimumSystemVersion'] as String?, 32 | minimumOperatingSystemVersionIsOK: 33 | json['minimumOperatingSystemVersionIsOK'] as bool?, 34 | maximumSystemVersion: json['maximumSystemVersion'] as String?, 35 | maximumOperatingSystemVersionIsOK: 36 | json['maximumOperatingSystemVersionIsOK'] as bool?, 37 | channel: json['channel'] as String?, 38 | ); 39 | 40 | Map _$AppcastItemToJson(AppcastItem instance) => 41 | { 42 | 'versionString': instance.versionString, 43 | 'displayVersionString': instance.displayVersionString, 44 | 'fileURL': instance.fileURL, 45 | 'contentLength': instance.contentLength, 46 | 'infoURL': instance.infoURL, 47 | 'title': instance.title, 48 | 'dateString': instance.dateString, 49 | 'releaseNotesURL': instance.releaseNotesURL, 50 | 'itemDescription': instance.itemDescription, 51 | 'itemDescriptionFormat': instance.itemDescriptionFormat, 52 | 'fullReleaseNotesURL': instance.fullReleaseNotesURL, 53 | 'minimumSystemVersion': instance.minimumSystemVersion, 54 | 'minimumOperatingSystemVersionIsOK': 55 | instance.minimumOperatingSystemVersionIsOK, 56 | 'maximumSystemVersion': instance.maximumSystemVersion, 57 | 'maximumOperatingSystemVersionIsOK': 58 | instance.maximumOperatingSystemVersionIsOK, 59 | 'channel': instance.channel, 60 | }; 61 | -------------------------------------------------------------------------------- /packages/auto_updater/lib/src/auto_updater.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:auto_updater/src/appcast.dart'; 4 | import 'package:auto_updater/src/updater_error.dart'; 5 | import 'package:auto_updater/src/updater_listener.dart'; 6 | import 'package:auto_updater_platform_interface/auto_updater_platform_interface.dart'; 7 | 8 | class AutoUpdater { 9 | AutoUpdater._() { 10 | _platform.sparkleEvents.listen(_handleSparkleEvents); 11 | } 12 | 13 | /// The shared instance of [AutoUpdater]. 14 | static final AutoUpdater instance = AutoUpdater._(); 15 | 16 | AutoUpdaterPlatform get _platform => AutoUpdaterPlatform.instance; 17 | 18 | final List _listeners = []; 19 | 20 | void _handleSparkleEvents(event) { 21 | UpdaterError? updaterError; 22 | Appcast? appcast; 23 | AppcastItem? appcastItem; 24 | 25 | String type = event['type'] as String; 26 | Map? data; 27 | if (event['data'] != null) { 28 | data = event['data'] as Map; 29 | if (data['error'] != null) { 30 | updaterError = UpdaterError( 31 | data['error'].toString(), 32 | ); 33 | } 34 | if (data['appcast'] != null) { 35 | appcast = Appcast.fromJson( 36 | Map.from( 37 | (data['appcast'] as Map).cast(), 38 | ), 39 | ); 40 | } 41 | if (data['appcastItem'] != null) { 42 | appcastItem = AppcastItem.fromJson( 43 | Map.from( 44 | (data['appcastItem'] as Map).cast(), 45 | ), 46 | ); 47 | } 48 | } 49 | for (var listener in _listeners) { 50 | switch (type) { 51 | case 'error': 52 | listener.onUpdaterError(updaterError); 53 | break; 54 | case 'checking-for-update': 55 | listener.onUpdaterCheckingForUpdate(appcast); 56 | break; 57 | case 'update-available': 58 | listener.onUpdaterUpdateAvailable(appcastItem); 59 | break; 60 | case 'update-not-available': 61 | listener.onUpdaterUpdateNotAvailable(updaterError); 62 | break; 63 | case 'update-downloaded': 64 | listener.onUpdaterUpdateDownloaded(appcastItem); 65 | break; 66 | case 'before-quit-for-update': 67 | listener.onUpdaterBeforeQuitForUpdate(appcastItem); 68 | break; 69 | } 70 | } 71 | } 72 | 73 | /// Adds a listener to the auto updater. 74 | void addListener(UpdaterListener listener) { 75 | _listeners.add(listener); 76 | } 77 | 78 | /// Removes a listener from the auto updater. 79 | void removeListener(UpdaterListener listener) { 80 | _listeners.remove(listener); 81 | } 82 | 83 | /// Sets the url and initialize the auto updater. 84 | Future setFeedURL(String feedUrl) { 85 | return _platform.setFeedURL(feedUrl); 86 | } 87 | 88 | /// Asks the server whether there is an update. You must call setFeedURL before using this API. 89 | Future checkForUpdates({bool? inBackground}) { 90 | return _platform.checkForUpdates( 91 | inBackground: inBackground, 92 | ); 93 | } 94 | 95 | /// Sets the auto update check interval, default 86400, minimum 3600, 0 to disable update 96 | Future setScheduledCheckInterval(int interval) { 97 | return _platform.setScheduledCheckInterval(interval); 98 | } 99 | } 100 | 101 | final autoUpdater = AutoUpdater.instance; 102 | -------------------------------------------------------------------------------- /packages/auto_updater/lib/src/updater_error.dart: -------------------------------------------------------------------------------- 1 | class UpdaterError extends Error { 2 | UpdaterError(this.message); 3 | 4 | final String message; 5 | 6 | @override 7 | String toString() { 8 | return 'UpdaterError: $message'; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/auto_updater/lib/src/updater_listener.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_updater/auto_updater.dart'; 2 | 3 | abstract mixin class UpdaterListener { 4 | void onUpdaterError(UpdaterError? error); 5 | void onUpdaterCheckingForUpdate(Appcast? appcast); 6 | void onUpdaterUpdateAvailable(AppcastItem? appcastItem); 7 | void onUpdaterUpdateNotAvailable(UpdaterError? error); 8 | void onUpdaterUpdateDownloaded(AppcastItem? appcastItem); 9 | void onUpdaterBeforeQuitForUpdate(AppcastItem? appcastItem); 10 | } 11 | -------------------------------------------------------------------------------- /packages/auto_updater/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater 2 | description: This plugin allows Flutter desktop apps to automatically update themselves (based on sparkle and winsparkle). 3 | version: 1.0.0 4 | homepage: https://github.com/leanflutter/auto_updater 5 | 6 | platforms: 7 | macos: 8 | windows: 9 | 10 | topics: 11 | - auto-updater 12 | 13 | environment: 14 | sdk: ">=3.0.0 <4.0.0" 15 | flutter: ">=3.3.0" 16 | 17 | dependencies: 18 | auto_updater_macos: ^1.0.0 19 | auto_updater_platform_interface: ^1.0.0 20 | auto_updater_windows: ^1.0.0 21 | flutter: 22 | sdk: flutter 23 | json_annotation: ^4.8.0 24 | path: ^1.8.3 25 | 26 | dev_dependencies: 27 | build_runner: ^2.3.3 28 | dependency_validator: ^3.0.0 29 | flutter_test: 30 | sdk: flutter 31 | json_serializable: ^6.6.0 32 | mostly_reasonable_lints: ^0.1.2 33 | 34 | flutter: 35 | plugin: 36 | platforms: 37 | macos: 38 | default_package: auto_updater_macos 39 | windows: 40 | default_package: auto_updater_windows 41 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "7482962148e8d758338d8a28f589f317e1e42ba4" 8 | channel: "stable" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4 17 | base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4 18 | - platform: macos 19 | create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4 20 | base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | * First major release. 4 | 5 | ## 0.2.0 6 | 7 | * First release. 8 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 LiJianying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/auto_updater_macos/README.md: -------------------------------------------------------------------------------- 1 | # auto_updater_macos 2 | 3 | [![pub version][pub-image]][pub-url] 4 | 5 | [pub-image]: https://img.shields.io/pub/v/auto_updater_macos.svg 6 | [pub-url]: https://pub.dev/packages/auto_updater_macos 7 | 8 | The macOS implementation of [auto_updater](https://pub.dev/packages/auto_updater). 9 | 10 | ## License 11 | 12 | [MIT](./LICENSE) 13 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:mostly_reasonable_lints/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/macos/Classes/AutoUpdater.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | import Sparkle 4 | 5 | extension SUAppcast { 6 | public func toDictionary() -> NSDictionary { 7 | let dict: NSDictionary = [ 8 | "items": self.items.map({ item in 9 | return item.toDictionary() 10 | }), 11 | ] 12 | return dict; 13 | } 14 | } 15 | 16 | extension SUAppcastItem { 17 | 18 | 19 | public func toDictionary() -> NSDictionary { 20 | let dict: NSDictionary = [ 21 | "versionString": self.versionString, 22 | "displayVersionString": self.displayVersionString, 23 | "fileURL": self.fileURL?.absoluteString ?? "", 24 | "contentLength": self.contentLength, 25 | "infoURL": self.infoURL?.absoluteString ?? "", 26 | "title":self.title ?? "", 27 | "dateString": self.dateString ?? "", 28 | "releaseNotesURL":self.releaseNotesURL?.absoluteString ?? "", 29 | "itemDescription":self.itemDescription ?? "", 30 | "itemDescriptionFormat": self.itemDescriptionFormat ?? "", 31 | "fullReleaseNotesURL": self.fullReleaseNotesURL ?? "", 32 | "minimumSystemVersion": self.minimumSystemVersion ?? "", 33 | "minimumOperatingSystemVersionIsOK": self.minimumOperatingSystemVersionIsOK, 34 | "maximumSystemVersion": self.maximumSystemVersion ?? "", 35 | "maximumOperatingSystemVersionIsOK": self.maximumOperatingSystemVersionIsOK, 36 | "channel": self.channel ?? "", 37 | ] 38 | return dict; 39 | } 40 | } 41 | 42 | public class AutoUpdater: NSObject, SPUUpdaterDelegate { 43 | var _userDriver: SPUStandardUserDriver? 44 | var _updater: SPUUpdater? 45 | var feedURL: URL? 46 | public var onEvent:((String, NSDictionary) -> Void)? 47 | 48 | override init() { 49 | super.init() 50 | let hostBundle: Bundle = Bundle.main 51 | 52 | _userDriver = SPUStandardUserDriver(hostBundle: hostBundle, delegate: nil) 53 | _updater = SPUUpdater( 54 | hostBundle: hostBundle, 55 | applicationBundle: hostBundle, 56 | userDriver: _userDriver!, 57 | delegate: self 58 | ) 59 | _updater?.clearFeedURLFromUserDefaults() 60 | try? _updater?.start() 61 | } 62 | 63 | public func feedURLString(for updater: SPUUpdater) -> String? { 64 | return feedURL?.absoluteString 65 | } 66 | 67 | public func setFeedURL(_ feedURL: URL?) { 68 | self.feedURL = feedURL 69 | try? _updater?.start() 70 | } 71 | 72 | public func checkForUpdates() { 73 | _updater?.checkForUpdates() 74 | } 75 | 76 | public func checkForUpdatesInBackground() { 77 | _updater?.checkForUpdatesInBackground() 78 | } 79 | 80 | public func setScheduledCheckInterval(_ interval: Int) { 81 | _updater?.updateCheckInterval = TimeInterval(interval) 82 | } 83 | 84 | // SPUUpdaterDelegate 85 | 86 | public func updater(_ updater: SPUUpdater, didAbortWithError error: Error) { 87 | let data: NSDictionary = [ 88 | "error": error.localizedDescription, 89 | ] 90 | _emitEvent("error", data); 91 | } 92 | 93 | public func updater(_ updater: SPUUpdater, didFinishLoading appcast: SUAppcast) { 94 | let data: NSDictionary = [ 95 | "appcast": appcast.toDictionary() 96 | ] 97 | _emitEvent("checking-for-update", data) 98 | } 99 | 100 | public func updater(_ updater: SPUUpdater, didFindValidUpdate item: SUAppcastItem) { 101 | let data: NSDictionary = [ 102 | "appcastItem": item.toDictionary() 103 | ] 104 | _emitEvent("update-available", data) 105 | } 106 | 107 | public func updaterDidNotFindUpdate(_ updater: SPUUpdater, error: Error) { 108 | let data: NSDictionary = [ 109 | "error": error.localizedDescription, 110 | ] 111 | _emitEvent("update-not-available", data) 112 | } 113 | 114 | public func updater(_ updater: SPUUpdater, didDownloadUpdate item: SUAppcastItem) { 115 | let data: NSDictionary = [ 116 | "appcastItem": item.toDictionary() 117 | ] 118 | _emitEvent("update-downloaded", data) 119 | } 120 | 121 | public func updater(_ updater: SPUUpdater, willInstallUpdateOnQuit item: SUAppcastItem, immediateInstallationBlock immediateInstallHandler: @escaping () -> Void) -> Bool { 122 | let data: NSDictionary = [ 123 | "appcastItem": item.toDictionary() 124 | ] 125 | _emitEvent("before-quit-for-update", data) 126 | return true 127 | } 128 | 129 | public func _emitEvent(_ eventName: String, _ data: NSDictionary) { 130 | if (onEvent != nil) { 131 | onEvent!(eventName, data) 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/macos/Classes/AutoUpdaterMacosPlugin.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | public class AutoUpdaterMacosPlugin: NSObject, FlutterPlugin,FlutterStreamHandler { 5 | private var _eventSink: FlutterEventSink? 6 | 7 | private var autoUpdater: AutoUpdater = AutoUpdater() 8 | 9 | public static func register(with registrar: FlutterPluginRegistrar) { 10 | let channel = FlutterMethodChannel(name: "dev.leanflutter.plugins/auto_updater", binaryMessenger: registrar.messenger) 11 | let instance = AutoUpdaterMacosPlugin() 12 | registrar.addMethodCallDelegate(instance, channel: channel) 13 | let eventChannel = FlutterEventChannel(name: "dev.leanflutter.plugins/auto_updater_event", binaryMessenger: registrar.messenger) 14 | eventChannel.setStreamHandler(instance) 15 | instance.autoUpdater.onEvent = { 16 | (eventName: String, eventData: NSDictionary) in 17 | guard let eventSink = instance._eventSink else { 18 | return 19 | } 20 | let event: NSDictionary = [ 21 | "type": eventName, 22 | "data": eventData 23 | ] 24 | eventSink(event) 25 | } 26 | } 27 | 28 | public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { 29 | self._eventSink = events 30 | return nil; 31 | } 32 | 33 | public func onCancel(withArguments arguments: Any?) -> FlutterError? { 34 | self._eventSink = nil 35 | return nil 36 | } 37 | 38 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 39 | let args: [String: Any] = call.arguments as? [String: Any] ?? [:] 40 | 41 | switch call.method { 42 | case "setFeedURL": 43 | let feedURL = URL(string: args["feedURL"] as! String) 44 | autoUpdater.setFeedURL(feedURL) 45 | result(true) 46 | break 47 | case "checkForUpdates": 48 | let inBackground = args["inBackground"] as! Bool 49 | if(inBackground) { 50 | autoUpdater.checkForUpdatesInBackground() 51 | }else { 52 | autoUpdater.checkForUpdates() 53 | } 54 | result(true) 55 | break 56 | case "setScheduledCheckInterval": 57 | let interval = args["interval"] as! Int 58 | autoUpdater.setScheduledCheckInterval(interval) 59 | result(true) 60 | break 61 | default: 62 | result(FlutterMethodNotImplemented) 63 | } 64 | } 65 | } 66 | 67 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/macos/auto_updater_macos.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint auto_updater_macos.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'auto_updater_macos' 7 | s.version = '0.0.1' 8 | s.summary = 'A new Flutter plugin project.' 9 | s.description = <<-DESC 10 | A new Flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | 16 | s.source = { :path => '.' } 17 | s.source_files = 'Classes/**/*' 18 | s.dependency 'FlutterMacOS' 19 | s.dependency 'Sparkle' 20 | 21 | s.platform = :osx, '10.11' 22 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES' } 23 | s.swift_version = '5.0' 24 | end 25 | -------------------------------------------------------------------------------- /packages/auto_updater_macos/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater_macos 2 | description: macOS implementation of the auto_updater plugin. 3 | version: 1.0.0 4 | repository: https://github.com/leanflutter/auto_updater/tree/main/packages/auto_updater_macos 5 | 6 | environment: 7 | sdk: '>=3.0.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | plugin_platform_interface: ^2.0.0 14 | 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | mostly_reasonable_lints: ^0.1.2 19 | 20 | flutter: 21 | plugin: 22 | implements: auto_updater 23 | platforms: 24 | macos: 25 | pluginClass: AutoUpdaterMacosPlugin 26 | 27 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "7482962148e8d758338d8a28f589f317e1e42ba4" 8 | channel: "stable" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 7482962148e8d758338d8a28f589f317e1e42ba4 17 | base_revision: 7482962148e8d758338d8a28f589f317e1e42ba4 18 | 19 | # User provided section 20 | 21 | # List of Local paths (relative to this file) that should be 22 | # ignored by the migrate tool. 23 | # 24 | # Files that are not part of the templates will be ignored by default. 25 | unmanaged_files: 26 | - 'lib/main.dart' 27 | - 'ios/Runner.xcodeproj/project.pbxproj' 28 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | * First major release. 4 | 5 | ## 0.2.0 6 | 7 | * First release. 8 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 LiJianying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/README.md: -------------------------------------------------------------------------------- 1 | # auto_updater_platform_interface 2 | 3 | [![pub version][pub-image]][pub-url] 4 | 5 | [pub-image]: https://img.shields.io/pub/v/auto_updater_platform_interface.svg 6 | [pub-url]: https://pub.dev/packages/auto_updater_platform_interface 7 | 8 | A common platform interface for the [auto_updater](https://pub.dev/packages/auto_updater) plugin. 9 | 10 | ## Usage 11 | 12 | To implement a new platform-specific implementation of auto_updater, extend `AutoUpdaterPlatform` with an implementation that performs the platform-specific behavior, and when you register your plugin, set the default `AutoUpdaterPlatform` by calling `AutoUpdaterPlatform.instance = MyPlatformAutoUpdater()`. 13 | 14 | ## License 15 | 16 | [MIT](./LICENSE) 17 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:mostly_reasonable_lints/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/lib/auto_updater_platform_interface.dart: -------------------------------------------------------------------------------- 1 | library auto_updater_platform_interface; 2 | 3 | export 'src/auto_updater_method_channel.dart'; 4 | export 'src/auto_updater_platform_interface.dart'; 5 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/lib/src/auto_updater_method_channel.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_updater_platform_interface/src/auto_updater_platform_interface.dart'; 2 | import 'package:flutter/foundation.dart'; 3 | import 'package:flutter/services.dart'; 4 | 5 | /// An implementation of [AutoUpdaterPlatform] that uses method channels. 6 | class MethodChannelAutoUpdater extends AutoUpdaterPlatform { 7 | /// The method channel used to interact with the native platform. 8 | @visibleForTesting 9 | final methodChannel = const MethodChannel( 10 | 'dev.leanflutter.plugins/auto_updater', 11 | ); 12 | 13 | /// The event channel used to receive events from the native platform. 14 | @visibleForTesting 15 | final eventChannel = const EventChannel( 16 | 'dev.leanflutter.plugins/auto_updater_event', 17 | ); 18 | 19 | @override 20 | Stream> get sparkleEvents { 21 | return eventChannel.receiveBroadcastStream().cast>(); 22 | } 23 | 24 | @override 25 | Future setFeedURL(String feedUrl) async { 26 | final Map arguments = { 27 | 'feedURL': feedUrl, 28 | }; 29 | await methodChannel.invokeMethod('setFeedURL', arguments); 30 | } 31 | 32 | @override 33 | Future checkForUpdates({bool? inBackground}) async { 34 | final Map arguments = { 35 | 'inBackground': inBackground ?? false, 36 | }; 37 | await methodChannel.invokeMethod('checkForUpdates', arguments); 38 | } 39 | 40 | @override 41 | Future setScheduledCheckInterval(int interval) async { 42 | final Map arguments = { 43 | 'interval': interval, 44 | }; 45 | await methodChannel.invokeMethod('setScheduledCheckInterval', arguments); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/lib/src/auto_updater_platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'package:auto_updater_platform_interface/src/auto_updater_method_channel.dart'; 2 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 3 | 4 | abstract class AutoUpdaterPlatform extends PlatformInterface { 5 | /// Constructs a AutoUpdaterPlatform. 6 | AutoUpdaterPlatform() : super(token: _token); 7 | 8 | static final Object _token = Object(); 9 | 10 | static AutoUpdaterPlatform _instance = MethodChannelAutoUpdater(); 11 | 12 | /// The default instance of [AutoUpdaterPlatform] to use. 13 | /// 14 | /// Defaults to [MethodChannelAutoUpdater]. 15 | static AutoUpdaterPlatform get instance => _instance; 16 | 17 | /// Platform-specific implementations should set this with their own 18 | /// platform-specific class that extends [AutoUpdaterPlatform] when 19 | /// they register themselves. 20 | static set instance(AutoUpdaterPlatform instance) { 21 | PlatformInterface.verifyToken(instance, _token); 22 | _instance = instance; 23 | } 24 | 25 | Stream> get sparkleEvents { 26 | throw UnimplementedError('sparkleEvents getter has not been implemented.'); 27 | } 28 | 29 | /// Sets the url and initialize the auto updater. 30 | Future setFeedURL(String feedUrl) async { 31 | throw UnimplementedError('setFeedURL() has not been implemented.'); 32 | } 33 | 34 | /// Asks the server whether there is an update. You must call setFeedURL before using this API. 35 | Future checkForUpdates({bool? inBackground}) async { 36 | throw UnimplementedError('checkForUpdates() has not been implemented.'); 37 | } 38 | 39 | /// Sets the auto update check interval, default 86400, minimum 3600, 0 to disable update 40 | Future setScheduledCheckInterval(int interval) async { 41 | throw UnimplementedError( 42 | 'setScheduledCheckInterval() has not been implemented.', 43 | ); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/auto_updater_platform_interface/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater_platform_interface 2 | description: A common platform interface for the auto_updater plugin. 3 | version: 1.0.0 4 | homepage: https://github.com/leanflutter/auto_updater/blob/main/packages/auto_updater_platform_interface 5 | 6 | environment: 7 | sdk: '>=3.0.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | plugin_platform_interface: ^2.1.8 14 | 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | mostly_reasonable_lints: ^0.1.2 19 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | build/ 30 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "67457e669f79e9f8d13d7a68fe09775fefbb79f4" 8 | channel: "stable" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 17 | base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 18 | - platform: windows 19 | create_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 20 | base_revision: 67457e669f79e9f8d13d7a68fe09775fefbb79f4 21 | 22 | # User provided section 23 | 24 | # List of Local paths (relative to this file) that should be 25 | # ignored by the migrate tool. 26 | # 27 | # Files that are not part of the templates will be ignored by default. 28 | unmanaged_files: 29 | - 'lib/main.dart' 30 | - 'ios/Runner.xcodeproj/project.pbxproj' 31 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.0.0 2 | 3 | * First major release. 4 | 5 | ## 0.2.1 6 | 7 | * chore(windows): Support before-quit-for-update event 8 | 9 | ## 0.2.0 10 | 11 | * First release. 12 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022-2024 LiJianying 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages/auto_updater_windows/README.md: -------------------------------------------------------------------------------- 1 | # auto_updater_windows 2 | 3 | [![pub version][pub-image]][pub-url] 4 | 5 | [pub-image]: https://img.shields.io/pub/v/auto_updater_windows.svg 6 | [pub-url]: https://pub.dev/packages/auto_updater_windows 7 | 8 | The Windows implementation of [auto_updater](https://pub.dev/packages/auto_updater). 9 | 10 | ## License 11 | 12 | [MIT](./LICENSE) 13 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:mostly_reasonable_lints/analysis_options.yaml 2 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater_windows 2 | description: Windows implementation of the auto_updater plugin. 3 | version: 1.0.0 4 | repository: https://github.com/leanflutter/auto_updater/tree/main/packages/auto_updater_windows 5 | 6 | environment: 7 | sdk: '>=3.0.0 <4.0.0' 8 | flutter: '>=3.3.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | plugin_platform_interface: ^2.0.0 14 | 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | mostly_reasonable_lints: ^0.1.2 19 | 20 | flutter: 21 | plugin: 22 | implements: auto_updater 23 | platforms: 24 | windows: 25 | pluginClass: AutoUpdaterWindowsPluginCApi 26 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | 19 | !WinSparkle-0.8.1/x64 -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The Flutter tooling requires that developers have a version of Visual Studio 2 | # installed that includes CMake 3.14 or later. You should not increase this 3 | # version, as doing so will cause the plugin to fail to compile for some 4 | # customers of the plugin. 5 | cmake_minimum_required(VERSION 3.14) 6 | 7 | # Project-level configuration. 8 | set(PROJECT_NAME "auto_updater_windows") 9 | project(${PROJECT_NAME} LANGUAGES CXX) 10 | 11 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent 12 | # versions of CMake. 13 | cmake_policy(VERSION 3.14...3.25) 14 | 15 | # This value is used when generating builds using this plugin, so it must 16 | # not be changed 17 | set(PLUGIN_NAME "auto_updater_windows_plugin") 18 | 19 | # WinSparkle 20 | set(WIN_SPARKLE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/WinSparkle-0.8.1") 21 | set(WIN_SPARKLE_BINARIES "${WIN_SPARKLE_DIR}/x64/Release/WinSparkle.dll") 22 | set(WIN_SPARKLE_LIBRARIES "${WIN_SPARKLE_DIR}/x64/Release/WinSparkle.lib") 23 | 24 | # Any new source files that you add to the plugin should be added here. 25 | list(APPEND PLUGIN_SOURCES 26 | "auto_updater_windows_plugin.cpp" 27 | "auto_updater_windows_plugin.h" 28 | ) 29 | 30 | # Define the plugin library target. Its name must not be changed (see comment 31 | # on PLUGIN_NAME above). 32 | add_library(${PLUGIN_NAME} SHARED 33 | "include/auto_updater_windows/auto_updater_windows_plugin_c_api.h" 34 | "auto_updater_windows_plugin_c_api.cpp" 35 | ${PLUGIN_SOURCES} 36 | ) 37 | 38 | # Apply a standard set of build settings that are configured in the 39 | # application-level CMakeLists.txt. This can be removed for plugins that want 40 | # full control over build settings. 41 | apply_standard_settings(${PLUGIN_NAME}) 42 | 43 | # Symbols are hidden by default to reduce the chance of accidental conflicts 44 | # between plugins. This should not be removed; any symbols that should be 45 | # exported should be explicitly exported with the FLUTTER_PLUGIN_EXPORT macro. 46 | set_target_properties(${PLUGIN_NAME} PROPERTIES 47 | CXX_VISIBILITY_PRESET hidden) 48 | target_compile_definitions(${PLUGIN_NAME} PRIVATE FLUTTER_PLUGIN_IMPL) 49 | 50 | # Source include directories and library dependencies. Add any plugin-specific 51 | # dependencies here. 52 | target_include_directories(${PLUGIN_NAME} INTERFACE 53 | "${CMAKE_CURRENT_SOURCE_DIR}/include" 54 | "${WIN_SPARKLE_DIR}/include" 55 | ) 56 | target_link_libraries(${PLUGIN_NAME} PRIVATE flutter flutter_wrapper_plugin) 57 | target_link_libraries(${PLUGIN_NAME} PRIVATE ${WIN_SPARKLE_LIBRARIES}) 58 | 59 | # List of absolute paths to libraries that should be bundled with the plugin. 60 | # This list could contain prebuilt libraries, or libraries created by an 61 | # external build triggered from this build file. 62 | set(auto_updater_windows_bundled_libraries 63 | "" 64 | ${WIN_SPARKLE_BINARIES} 65 | PARENT_SCOPE 66 | ) 67 | 68 | # === Tests === 69 | # These unit tests can be run from a terminal after building the example, or 70 | # from Visual Studio after opening the generated solution file. 71 | 72 | # Only enable test builds when building the example (which sets this variable) 73 | # so that plugin clients aren't building the tests. 74 | if (${include_${PROJECT_NAME}_tests}) 75 | set(TEST_RUNNER "${PROJECT_NAME}_test") 76 | enable_testing() 77 | 78 | # Add the Google Test dependency. 79 | include(FetchContent) 80 | FetchContent_Declare( 81 | googletest 82 | URL https://github.com/google/googletest/archive/release-1.11.0.zip 83 | ) 84 | # Prevent overriding the parent project's compiler/linker settings 85 | set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) 86 | # Disable install commands for gtest so it doesn't end up in the bundle. 87 | set(INSTALL_GTEST OFF CACHE BOOL "Disable installation of googletest" FORCE) 88 | FetchContent_MakeAvailable(googletest) 89 | 90 | # The plugin's C API is not very useful for unit testing, so build the sources 91 | # directly into the test binary rather than using the DLL. 92 | add_executable(${TEST_RUNNER} 93 | test/auto_updater_windows_plugin_test.cpp 94 | ${PLUGIN_SOURCES} 95 | ) 96 | apply_standard_settings(${TEST_RUNNER}) 97 | target_include_directories(${TEST_RUNNER} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}") 98 | target_link_libraries(${TEST_RUNNER} PRIVATE flutter_wrapper_plugin) 99 | target_link_libraries(${TEST_RUNNER} PRIVATE gtest_main gmock) 100 | # flutter_wrapper_plugin has link dependencies on the Flutter DLL. 101 | add_custom_command(TARGET ${TEST_RUNNER} POST_BUILD 102 | COMMAND ${CMAKE_COMMAND} -E copy_if_different 103 | "${FLUTTER_LIBRARY}" $ 104 | ) 105 | 106 | # Enable automatic test discovery. 107 | include(GoogleTest) 108 | gtest_discover_tests(${TEST_RUNNER}) 109 | endif() 110 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/ARM64/Release/WinSparkle.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/ARM64/Release/WinSparkle.dll -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/ARM64/Release/WinSparkle.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/ARM64/Release/WinSparkle.lib -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/ARM64/Release/WinSparkle.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/ARM64/Release/WinSparkle.pdb -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/AUTHORS: -------------------------------------------------------------------------------- 1 | Maintainer: 2 | 3 | Vaclav Slavik 4 | 5 | 6 | Contributors: 7 | 8 | Kohan Ikin 9 | Christian L. Jacobsen 10 | Littleboy 11 | Vasco Veloso 12 | Jonas Emanuel Mueller 13 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/COPYING: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009-2023 Vaclav Slavik 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | 22 | 23 | 24 | This product includes software developed by the OpenSSL Project 25 | for use in the OpenSSL Toolkit (http://www.openssl.org/). 26 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/COPYING.expat: -------------------------------------------------------------------------------- 1 | Copyright (c) 1998-2000 Thai Open Source Software Center Ltd and Clark Cooper 2 | Copyright (c) 2001-2017 Expat maintainers 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included 13 | in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/NEWS: -------------------------------------------------------------------------------- 1 | Version 0.8.1 2 | ------------- 3 | 4 | - Fixed release notes not shown if is malformed 5 | and has whitespace around the URL. 6 | 7 | 8 | Version 0.8.0 9 | ------------- 10 | 11 | - Added support for modern Edge/WebView2 browser for release notes. 12 | - Added win_sparkle_set_update_dismissed_callback() and 13 | win_sparkle_set_update_postponed_callback() callbacks. 14 | - Added partiaul support for tag. 15 | - Links in release notes now open in user's default browser as they should. 16 | - Added support for Visual Studio 2019 and 2022. 17 | - Added official NuGet package. 18 | - Added support for ARM64 architecture. 19 | - This version drops official support for Windows XP. It may still be possible 20 | to target it with vs*_xp toolsets, but would probably require at least 21 | disabling WebView2. Prebuilt binaries and NuGet package don't support XP. 22 | 23 | 24 | Version 0.7.0 25 | ------------- 26 | 27 | - Added support for providing custom HTTP headers when fetch appcast feeds. 28 | - Added support for overriding WinSparkle config functions. 29 | - Reduced size of WinSparkle.dll. 30 | 31 | 32 | Version 0.6.0 33 | ------------- 34 | 35 | - Added support for validating DSA signatures. 36 | - Fixes to window placement. 37 | - Fixed regression in win_sparkle_check_update_without_ui() not checking 38 | immediately. 39 | 40 | 41 | Version 0.5.7 42 | ------------- 43 | 44 | - Fixed issue with downloads from servers without keep-alive support. 45 | 46 | 47 | Version 0.5.6 48 | ------------- 49 | 50 | - Includes security fixes for Expat XML parser (CVE-2017-11742). 51 | 52 | 53 | Version 0.5.5 54 | ------------- 55 | 56 | - Fixed regression in initial update checking introduced in 0.5.4. 57 | 58 | 59 | Version 0.5.4 60 | ------------- 61 | 62 | - Updates are now checked in background periodically even in applications that 63 | are running for a long time. 64 | - HTTP caching is now disabled more aggressively. 65 | - Fixed handling of downloads from URLs with query parameters. 66 | - Includes security fixes for Expat XML parser. 67 | 68 | 69 | Version 0.5.3 70 | ------------- 71 | 72 | - Downloads are now cancellable. 73 | - Fixed an issue with parsing some appcasts (#123). 74 | - Verify UpdateTempDir's validity before deleting it. 75 | 76 | 77 | Version 0.5.2 78 | ------------- 79 | 80 | - Includes security fixes for Expat XML parser. 81 | 82 | 83 | Version 0.5.1 84 | ------------- 85 | 86 | - Includes fix for the CVE-2016-0718 vulnerability in Expat XML parser. 87 | - Added Pascal bindings. 88 | - Fixes for RTL languages, added Arabic and Hebrew translations. 89 | 90 | 91 | Version 0.5 92 | ----------- 93 | 94 | - Added translations support (32 languages are included at the moment). 95 | - HiDPI support. 96 | - Updated Expat XML parser to 2.1.1 (security fixes, CVE-2015-1283). 97 | - Support for minimumSystemVersion and for specifying 32/64 versions. 98 | - Added win_sparkle_check_update_with_ui_and_install() for forcefully 99 | installing available updates. 100 | - Added more callbacks for various events during updating. 101 | - Misc cosmetic fixes. 102 | 103 | 104 | Version 0.4 105 | ----------- 106 | 107 | - Added API for gracefully shutting down the host app. 108 | - Added the ability to disable automatic checks. 109 | - Added the ability to change the update checks interval. 110 | - Added x64 support. 111 | - Added Visual Studio 201x project files. 112 | - Release notes included in appcast's element are now recognized. 113 | - Added support for build numbers and shortVersionString. 114 | - Added support for sparkle:os="windows" attribute on appcast items. 115 | - Fixed appcasts over HTTPS. 116 | - Use application icon in the UI. 117 | - In-app downloads. 118 | 119 | 120 | Version 0.3 121 | ----------- 122 | 123 | - Added win_sparkle_set_app_details() for setting app metadata from code, 124 | as an alternative to their extraction from resources. 125 | - It is no longer necessary to call win_sparkle_set_appcast_url(), the 126 | feed can be specified in FeedURL resource with type set to APPCAST. 127 | - Added win_sparkle_set_registry_path(). 128 | 129 | 130 | Version 0.2 131 | ----------- 132 | 133 | - Display error if update info couldn't be retrieved while manually checking 134 | for updates. 135 | - WinSparkle window is now resizable only when showing release notes. 136 | - Bypass cache and proxies in manual checks. 137 | 138 | 139 | Version 0.1.1 140 | ------------- 141 | 142 | - Fixed Sparkle namespace in appcast parser; it now looks for the correct 143 | `http://www.andymatuschak.org/xml-namespaces/sparkle` value. Appcasts 144 | using the incorrect `http://www.andymatuschak.org/xml-namespaces` 145 | URI must be updated. 146 | 147 | 148 | Version 0.1 149 | ----------- 150 | 151 | - Initial release. 152 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/README.md: -------------------------------------------------------------------------------- 1 | [![Crowdin](https://d322cqt584bo4o.cloudfront.net/winsparkle/localized.png)](https://crowdin.com/project/winsparkle) 2 | 3 | About 4 | ------- 5 | 6 | WinSparkle is a plug-and-forget software update library for Windows 7 | applications. It is heavily inspired by the Sparkle framework for OS X 8 | written by Andy Matuschak and others, to the point of sharing the same 9 | updates format (appcasts) and having very similar user interface. 10 | 11 | See https://winsparkle.org for more information about WinSparkle. 12 | 13 | Documentation: [wiki](https://github.com/vslavik/winsparkle/wiki) and 14 | the [winsparkle.h header](https://github.com/vslavik/winsparkle/blob/master/include/winsparkle.h). 15 | 16 | 17 | Using prebuilt binaries 18 | ------------------------- 19 | 20 | The easiest way to use WinSparkle is to either download the prebuilt `WinSparkle.dll` 21 | binary from releases or use the `WinSparkle` [NuGet package](https://www.nuget.org/packages/WinSparkle/). 22 | Prebuilt binaries are available for x86, x64 and arm64 platforms. 23 | 24 | 25 | Bindings 26 | ---------- 27 | 28 | WinSparkle has a C API that makes it easy to use from many modern languages in addition to C/C++. In addition to that, several bindings for popular languages exist: 29 | 30 | * [How to use with C#/.NET](https://github.com/vslavik/winsparkle/wiki/Basic-Setup#managed-code--net--c-applications) 31 | * [Python](https://pypi.org/project/pywinsparkle/) 32 | * [Go](https://github.com/abemedia/go-winsparkle) 33 | * [Pascal](https://github.com/vslavik/winsparkle/tree/master/pascal) binding bundled with WinSparkle 34 | 35 | 36 | Building from sources 37 | ----------------------- 38 | 39 | If you prefer to build WinSparkle yourself, you can do so. You'll have to 40 | compile from a git checkout; some of the dependencies are included as git 41 | submodules. 42 | 43 | Check the sources out and initialize the submodules: 44 | 45 | $ git clone https://github.com/vslavik/winsparkle.git 46 | $ cd winsparkle 47 | $ git submodule init 48 | $ git submodule update 49 | 50 | To compile the library, just open `WinSparkle.sln` (or the one corresponding to 51 | your compiler version) solution and build it. 52 | 53 | At the moment, projects for Visual C++ (2010 and up) are provided, so you'll 54 | need that (Express/Community edition suffices). In principle, there's nothing 55 | in the code preventing it from being compiled by other compilers. 56 | 57 | There are also unsupported CMake build files in the cmake directory. 58 | 59 | DSA signatures 60 | --------------- 61 | 62 | WinSparkle uses exactly same mechanism for signing and signature verification 63 | as [Sparkle Project](https://sparkle-project.org/documentation/#dsa-signatures) 64 | does. Its tools and verification methods are fully compatible. 65 | 66 | You may use any compatible way to sign your update. 67 | To achieve this, you need to sign SHA1 (in binary form) of your update file 68 | with DSA private key, using SHA1 digest. 69 | 70 | WinSparkle provides tools to generate keys and sign the update using OpenSSL. 71 | 72 | You need `openssl.exe` available on Windows to use those tools (available as 73 | [precompiled binary][OpenSSL binaries]). 74 | 75 | Alternatively, you can generate keys and sign your updates even on macOS or Linux, 76 | using [tools provided by Sparkle project](https://github.com/sparkle-project/Sparkle/tree/master/bin). 77 | 78 | #### Prepare signing with DSA signatures: 79 | 80 | - First, make yourself a pair of DSA keys. This needs to be done only once. 81 | WinSparkle includes a tool to help: `bin\generate_keys.bat` 82 | - Back up your private key (dsa_priv.pem) and keep it safe. You don’t want 83 | anyone else getting it, and if you lose it, you may not be able to issue any 84 | new updates. 85 | - Add your public key (dsa_pub.pem) to your project either as Windows resource, 86 | or any other suitable way and provide it using WinSparkle API. 87 | 88 | #### Sign your update 89 | 90 | When your update is ready (e.g. `Updater.exe`), sign it and include signature 91 | to your appcast file: 92 | 93 | - Sign: `bin\sign_update.bat Updater.exe dsa_priv.pem` 94 | - Add standard output of previous command as `sparkle:dsaSignature` attribute 95 | of `enclosure` node of your appcast file. 96 | Alternatively `sparkle:dsaSignature` can be a child node of `enclosure`. 97 | 98 | 99 | Where can I get some examples? 100 | -------------------------------- 101 | 102 | Download the sources archive and have a look at the 103 | [examples/](https://github.com/vslavik/winsparkle/tree/master/examples) folder. 104 | 105 | 106 | Using latest development versions 107 | ----------------------------------- 108 | 109 | If you want to stay at the bleeding edge and use the latest, not yet released, 110 | version of WinSparkle, you can get its sources from public repository. 111 | WinSparkle uses git and and the sources are hosted on GitHub at 112 | https://github.com/vslavik/winsparkle 113 | 114 | WinSparkle uses submodules for some dependencies, so you have to initialize 115 | them after checking the tree out: 116 | 117 | $ git clone https://github.com/vslavik/winsparkle.git 118 | $ cd winsparkle 119 | $ git submodule init 120 | $ git submodule update 121 | 122 | Then compile WinSparkle as described above; no extra steps are required. 123 | 124 | [OpenSSL source]: https://www.openssl.org/source/ 125 | [OpenSSL binaries]: https://wiki.openssl.org/index.php/Binaries 126 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/Release/WinSparkle.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/Release/WinSparkle.dll -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/Release/WinSparkle.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/Release/WinSparkle.lib -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/Release/WinSparkle.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/Release/WinSparkle.pdb -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/bin/generate_keys.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | FOR %%i IN ("dsaparam.pem" "dsa_priv.pem" "dsa_pub.pem") DO ( 4 | if exist %%i ( 5 | echo There's already a %%i here! Move it aside or be more careful! 6 | exit /b 1 7 | ) 8 | ) 9 | 10 | openssl dsaparam 4096 > dsaparam.pem 11 | 12 | openssl gendsa -out dsa_priv.pem dsaparam.pem 13 | del /F /Q dsaparam.pem 14 | openssl dsa -in dsa_priv.pem -pubout -out dsa_pub.pem 15 | 16 | FOR %%i IN ("dsa_priv.pem" "dsa_pub.pem") DO ( 17 | if not exist %%i ( 18 | echo Failed to create %%i! 19 | exit /b 1 20 | ) 21 | ) 22 | 23 | echo[ 24 | echo Generated two files: 25 | echo dsa_priv.pem: your private key. Keep it secret and don't share it! 26 | echo dsa_pub.pem: public counterpart to include in youe app. 27 | 28 | echo BACK UP YOUR PRIVATE KEY AND KEEP IT SAFE! 29 | echo If you lose it, your users will be unable to upgrade! 30 | echo[ 31 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/bin/sign_update.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | set argC=0 4 | for %%i in (%*) do set /A argC+=1 5 | 6 | if not "%argC%"=="2" ( 7 | echo Usage: %0 update_file private_key 8 | exit /b 1 9 | ) 10 | 11 | openssl dgst -sha1 -binary < "%~1" | openssl dgst -sha1 -sign "%~2" | openssl enc -base64 12 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/include/winsparkle-version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WinSparkle (https://winsparkle.org) 3 | * 4 | * Copyright (C) 2009-2023 Vaclav Slavik 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a 7 | * copy of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | * DEALINGS IN THE SOFTWARE. 23 | * 24 | */ 25 | 26 | #ifndef _winsparkle_version_h_ 27 | #define _winsparkle_version_h_ 28 | 29 | /*--------------------------------------------------------------------------* 30 | Version information 31 | *--------------------------------------------------------------------------*/ 32 | 33 | #define WIN_SPARKLE_VERSION_MAJOR 0 34 | #define WIN_SPARKLE_VERSION_MINOR 8 35 | #define WIN_SPARKLE_VERSION_MICRO 1 36 | 37 | /** 38 | Checks if WinSparkle version is at least @a major.@a minor.@a micro. 39 | */ 40 | #define WIN_SPARKLE_CHECK_VERSION(major, minor, micro) \ 41 | ( \ 42 | WIN_SPARKLE_VERSION_MAJOR > (major) \ 43 | || \ 44 | (WIN_SPARKLE_VERSION_MAJOR == (major) && \ 45 | WIN_SPARKLE_VERSION_MINOR >= (minor)) \ 46 | || \ 47 | (WIN_SPARKLE_VERSION_MAJOR == (major) && \ 48 | WIN_SPARKLE_VERSION_MINOR == (minor) && \ 49 | WIN_SPARKLE_VERSION_MICRO >= (micro)) \ 50 | ) 51 | 52 | #define _WIN_SPARKLE_MAKE_STR(x) #x 53 | #define _WIN_SPARKLE_MAKE_VERSION_STR(a,b,c) \ 54 | _WIN_SPARKLE_MAKE_STR(a) "." _WIN_SPARKLE_MAKE_STR(b) "." _WIN_SPARKLE_MAKE_STR(c) 55 | 56 | /** 57 | WinSparkle version as a string in the form of e.g. "0.1.3". 58 | */ 59 | #define WIN_SPARKLE_VERSION_STRING \ 60 | _WIN_SPARKLE_MAKE_VERSION_STR(WIN_SPARKLE_VERSION_MAJOR, \ 61 | WIN_SPARKLE_VERSION_MINOR, \ 62 | WIN_SPARKLE_VERSION_MICRO) 63 | 64 | #endif // _winsparkle_version_h_ 65 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/include/winsparkle.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of WinSparkle (https://winsparkle.org) 3 | * 4 | * Copyright (C) 2009-2023 Vaclav Slavik 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a 7 | * copy of this software and associated documentation files (the "Software"), 8 | * to deal in the Software without restriction, including without limitation 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 | * and/or sell copies of the Software, and to permit persons to whom the 11 | * Software is furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 | * DEALINGS IN THE SOFTWARE. 23 | * 24 | */ 25 | 26 | #ifndef _winsparkle_h_ 27 | #define _winsparkle_h_ 28 | 29 | #include 30 | #include 31 | 32 | #include "winsparkle-version.h" 33 | 34 | #if !defined(BUILDING_WIN_SPARKLE) && defined(_MSC_VER) 35 | #pragma comment(lib, "WinSparkle.lib") 36 | #endif 37 | 38 | #ifdef __cplusplus 39 | extern "C" { 40 | #endif 41 | 42 | #ifdef BUILDING_WIN_SPARKLE 43 | #define WIN_SPARKLE_API __declspec(dllexport) 44 | #else 45 | #define WIN_SPARKLE_API __declspec(dllimport) 46 | #endif 47 | 48 | 49 | /// Return value for boolean functions to indicate unexpected error. 50 | /// Only used by functions or callbacks that are explicitly documented as using it. 51 | #define WINSPARKLE_RETURN_ERROR (-1) 52 | 53 | 54 | /*--------------------------------------------------------------------------* 55 | Initialization and shutdown 56 | *--------------------------------------------------------------------------*/ 57 | 58 | /** 59 | @name Initialization functions 60 | */ 61 | //@{ 62 | 63 | /** 64 | Starts WinSparkle. 65 | 66 | If WinSparkle is configured to check for updates on startup, proceeds 67 | to perform the check. You should only call this function when your app 68 | is initialized and shows its main window. 69 | 70 | @note This call doesn't block and returns almost immediately. If an 71 | update is available, the respective UI is shown later from a separate 72 | thread. 73 | 74 | @see win_sparkle_cleanup() 75 | */ 76 | WIN_SPARKLE_API void __cdecl win_sparkle_init(); 77 | 78 | /** 79 | Cleans up after WinSparkle. 80 | 81 | Should be called by the app when it's shutting down. Cancels any 82 | pending Sparkle operations and shuts down its helper threads. 83 | */ 84 | WIN_SPARKLE_API void __cdecl win_sparkle_cleanup(); 85 | 86 | //@} 87 | 88 | 89 | /*--------------------------------------------------------------------------* 90 | Language settings 91 | *--------------------------------------------------------------------------*/ 92 | 93 | /** 94 | @name Language settings 95 | 96 | These functions set user interface language. They must be called before 97 | win_sparkle_init() to have any effect. If none of them is called, WinSparkle 98 | detects the UI language automatically. 99 | */ 100 | //@{ 101 | 102 | /** 103 | Sets UI language from its ISO code. 104 | 105 | This function must be called before win_sparkle_init(). 106 | 107 | @param lang ISO 639 language code with an optional ISO 3116 country 108 | code, e.g. "fr", "pt-PT", "pt-BR" or "pt_BR", as used 109 | e.g. by ::GetThreadPreferredUILanguages() too. 110 | 111 | @since 0.5 112 | 113 | @see win_sparkle_set_langid() 114 | */ 115 | WIN_SPARKLE_API void __cdecl win_sparkle_set_lang(const char *lang); 116 | 117 | /** 118 | Sets UI language from its Win32 LANGID code. 119 | 120 | This function must be called before win_sparkle_init(). 121 | 122 | @param lang Language code (LANGID) as created by the MAKELANGID macro 123 | or returned by e.g. ::GetThreadUILanguage() 124 | 125 | @since 0.5 126 | 127 | @see win_sparkle_set_lang() 128 | */ 129 | WIN_SPARKLE_API void __cdecl win_sparkle_set_langid(unsigned short lang); 130 | 131 | //@} 132 | 133 | /*--------------------------------------------------------------------------* 134 | Configuration 135 | *--------------------------------------------------------------------------*/ 136 | 137 | /** 138 | @name Configuration functions 139 | 140 | Functions for setting up WinSparkle. 141 | 142 | All functions in this category can only be called @em before the first 143 | call to win_sparkle_init()! 144 | 145 | Typically, the application would configure WinSparkle on startup and then 146 | call win_sparkle_init(), all from its main thread. 147 | */ 148 | //@{ 149 | 150 | /** 151 | Sets URL for the app's appcast. 152 | 153 | Only http and https schemes are supported. 154 | 155 | If this function isn't called by the app, the URL is obtained from 156 | Windows resource named "FeedURL" of type "APPCAST". 157 | 158 | @param url URL of the appcast. 159 | 160 | @note Always use HTTPS feeds, do not use unencrypted HTTP! This is 161 | necessary to prevent both leaking user information and preventing 162 | various MITM attacks. 163 | 164 | @note See https://github.com/vslavik/winsparkle/wiki/Appcast-Feeds for 165 | more information about appcast feeds. 166 | */ 167 | WIN_SPARKLE_API void __cdecl win_sparkle_set_appcast_url(const char *url); 168 | 169 | /** 170 | Sets DSA public key. 171 | 172 | Only PEM format is supported. 173 | 174 | Public key will be used to verify DSA signature of the update file. 175 | PEM data will be set only if it contains valid DSA public key. 176 | 177 | If this function isn't called by the app, public key is obtained from 178 | Windows resource named "DSAPub" of type "DSAPEM". 179 | 180 | @param dsa_pub_pem DSA public key in PEM format. 181 | 182 | @return 1 if valid DSA public key provided, 0 otherwise. 183 | 184 | @since 0.6.0 185 | */ 186 | WIN_SPARKLE_API int __cdecl win_sparkle_set_dsa_pub_pem(const char *dsa_pub_pem); 187 | 188 | /** 189 | Sets application metadata. 190 | 191 | Normally, these are taken from VERSIONINFO/StringFileInfo resources, 192 | but if your application doesn't use them for some reason, using this 193 | function is an alternative. 194 | 195 | @param company_name Company name of the vendor. 196 | @param app_name Application name. This is both shown to the user 197 | and used in HTTP User-Agent header. 198 | @param app_version Version of the app, as string (e.g. "1.2" or "1.2rc1"). 199 | 200 | @note @a company_name and @a app_name are used to determine the location 201 | of WinSparkle settings in registry. 202 | (HKCU\Software\\\WinSparkle is used.) 203 | 204 | @since 0.3 205 | 206 | @see win_sparkle_set_app_build_version(); 207 | */ 208 | WIN_SPARKLE_API void __cdecl win_sparkle_set_app_details(const wchar_t *company_name, 209 | const wchar_t *app_name, 210 | const wchar_t *app_version); 211 | 212 | /** 213 | Sets application build version number. 214 | 215 | This is the internal version number that is not normally shown to the user. 216 | It can be used for finer granularity that official release versions, e.g. for 217 | interim builds. 218 | 219 | If this function is called, then the provided *build* number is used for comparing 220 | versions; it is compared to the "version" attribute in the appcast and corresponds 221 | to OS X Sparkle's CFBundleVersion handling. If used, then the appcast must 222 | also contain the "shortVersionString" attribute with human-readable display 223 | version string. The version passed to win_sparkle_set_app_details() 224 | corresponds to this and is used for display. 225 | 226 | @since 0.4 227 | 228 | @see win_sparkle_set_app_details() 229 | */ 230 | WIN_SPARKLE_API void __cdecl win_sparkle_set_app_build_version(const wchar_t *build); 231 | 232 | /** 233 | Set custom HTTP header for appcast checks. 234 | 235 | @since 0.7 236 | 237 | @see win_sparkle_clear_http_headers() 238 | */ 239 | WIN_SPARKLE_API void __cdecl win_sparkle_set_http_header(const char *name, const char *value); 240 | 241 | /** 242 | Clears all custom HTTP headers previously added using 243 | win_sparkle_set_http_header(). 244 | 245 | @since 0.7 246 | 247 | @see win_sparkle_set_http_header() 248 | */ 249 | WIN_SPARKLE_API void __cdecl win_sparkle_clear_http_headers(); 250 | 251 | /** 252 | Set the registry path where settings will be stored. 253 | 254 | Normally, these are stored in 255 | "HKCU\Software\\\WinSparkle" 256 | but if your application needs to store the data elsewhere for 257 | some reason, using this function is an alternative. 258 | 259 | Note that @a path is relative to HKCU/HKLM root and the root is not part 260 | of it. For example: 261 | @code 262 | win_sparkle_set_registry_path("Software\\My App\\Updates"); 263 | @endcode 264 | 265 | @param path Registry path where settings will be stored. 266 | 267 | @since 0.3 268 | */ 269 | WIN_SPARKLE_API void __cdecl win_sparkle_set_registry_path(const char *path); 270 | 271 | /// Type used to override WinSparkle configuration's read, write and delete functions 272 | typedef struct win_sparkle_config_methods_tag { 273 | /// Copy config value named @a name to the buffer pointed by @a buf, returns TRUE on success, FALSE on failure 274 | int(__cdecl *config_read)(const char *name, wchar_t *buf, size_t len, void *user_data); 275 | /// Write @a value as config value @a name 's new value 276 | void(__cdecl *config_write)(const char *name, const wchar_t *value, void *user_data); 277 | /// Delete config value named @a name 278 | void(__cdecl *config_delete)(const char *name, void *user_data); 279 | /// Arbitrary data which will be passed to the above functions, WinSparkle will not read or alter it. 280 | void *user_data; 281 | } win_sparkle_config_methods_t; 282 | 283 | 284 | /** 285 | Override WinSparkle's configuration read, write and delete functions. 286 | 287 | By default, WinSparkle will read, write and delete configuration values by 288 | interacting directly with Windows Registry. 289 | If you want to manage configuration by yourself, or if you don't want let WinSparkle 290 | write settings directly to the Windows Registry, you can provide your own functions 291 | to read, write and delete configuration. 292 | 293 | These functions needs to return TRUE on success, FALSE on failure. 294 | If you passed NULL as a configuration action (read, write or delete)'s function pointer, 295 | WinSparkle will use the default function for that action. 296 | 297 | @param config_methods Your own configuration read, write and delete functions. 298 | Pass NULL to let WinSparkle continue to use its default functions. 299 | 300 | @note There's no guarantee about the thread from which these functions are called, 301 | Make sure your functions are thread-safe. 302 | 303 | @since 0.7 304 | */ 305 | WIN_SPARKLE_API void __cdecl win_sparkle_set_config_methods(win_sparkle_config_methods_t *config_methods); 306 | 307 | /** 308 | Sets whether updates are checked automatically or only through a manual call. 309 | 310 | If disabled, win_sparkle_check_update_with_ui() must be used explicitly. 311 | 312 | @param state 1 to have updates checked automatically, 0 otherwise 313 | 314 | @since 0.4 315 | */ 316 | WIN_SPARKLE_API void __cdecl win_sparkle_set_automatic_check_for_updates(int state); 317 | 318 | /** 319 | Gets the automatic update checking state 320 | 321 | @return 1 if updates are set to be checked automatically, 0 otherwise 322 | 323 | @note Defaults to 0 when not yet configured (as happens on first start). 324 | 325 | @since 0.4 326 | */ 327 | WIN_SPARKLE_API int __cdecl win_sparkle_get_automatic_check_for_updates(); 328 | 329 | /** 330 | Sets the automatic update interval. 331 | 332 | @param interval The interval in seconds between checks for updates. 333 | The minimum update interval is 3600 seconds (1 hour). 334 | 335 | @since 0.4 336 | */ 337 | WIN_SPARKLE_API void __cdecl win_sparkle_set_update_check_interval(int interval); 338 | 339 | /** 340 | Gets the automatic update interval in seconds. 341 | 342 | Default value is one day. 343 | 344 | @since 0.4 345 | */ 346 | WIN_SPARKLE_API int __cdecl win_sparkle_get_update_check_interval(); 347 | 348 | /** 349 | Gets the time for the last update check. 350 | 351 | Default value is -1, indicating that the update check has never run. 352 | 353 | @since 0.4 354 | */ 355 | WIN_SPARKLE_API time_t __cdecl win_sparkle_get_last_check_time(); 356 | 357 | /// Callback type for win_sparkle_error_callback() 358 | typedef void (__cdecl *win_sparkle_error_callback_t)(); 359 | 360 | /** 361 | Set callback to be called when the updater encounters an error. 362 | 363 | @since 0.5 364 | */ 365 | WIN_SPARKLE_API void __cdecl win_sparkle_set_error_callback(win_sparkle_error_callback_t callback); 366 | 367 | /// Callback type for win_sparkle_can_shutdown_callback() 368 | typedef int (__cdecl *win_sparkle_can_shutdown_callback_t)(); 369 | 370 | /** 371 | Set callback for querying the application if it can be closed. 372 | 373 | This callback will be called to ask the host if it's ready to shut down, 374 | before attempting to launch the installer. The callback returns TRUE if 375 | the host application can be safely shut down or FALSE if not (e.g. because 376 | the user has unsaved documents). 377 | 378 | @note There's no guarantee about the thread from which the callback is called, 379 | except that it certainly *won't* be called from the app's main thread. 380 | Make sure the callback is thread-safe. 381 | 382 | @since 0.4 383 | 384 | @see win_sparkle_set_shutdown_request_callback() 385 | */ 386 | WIN_SPARKLE_API void __cdecl win_sparkle_set_can_shutdown_callback(win_sparkle_can_shutdown_callback_t callback); 387 | 388 | 389 | /// Callback type for win_sparkle_shutdown_request_callback() 390 | typedef void (__cdecl *win_sparkle_shutdown_request_callback_t)(); 391 | 392 | /** 393 | Set callback for shutting down the application. 394 | 395 | This callback will be called to ask the host to shut down immediately after 396 | launching the installer. Its implementation should gracefully terminate the 397 | application. 398 | 399 | It will only be called if the call to the callback set with 400 | win_sparkle_set_can_shutdown_callback() returns TRUE. 401 | 402 | @note There's no guarantee about the thread from which the callback is called, 403 | except that it certainly *won't* be called from the app's main thread. 404 | Make sure the callback is thread-safe. 405 | 406 | @since 0.4 407 | 408 | @see win_sparkle_set_can_shutdown_callback() 409 | */ 410 | WIN_SPARKLE_API void __cdecl win_sparkle_set_shutdown_request_callback(win_sparkle_shutdown_request_callback_t); 411 | 412 | /// Callback type for win_sparkle_did_find_update_callback() 413 | typedef void(__cdecl *win_sparkle_did_find_update_callback_t)(); 414 | 415 | /** 416 | Set callback to be called when the updater did find an update. 417 | 418 | This is useful in combination with 419 | win_sparkle_check_update_with_ui_and_install() as it allows you to perform 420 | some action after WinSparkle checks for updates. 421 | 422 | @since 0.5 423 | 424 | @see win_sparkle_did_not_find_update_callback() 425 | @see win_sparkle_check_update_with_ui_and_install() 426 | */ 427 | WIN_SPARKLE_API void __cdecl win_sparkle_set_did_find_update_callback(win_sparkle_did_find_update_callback_t callback); 428 | 429 | /// Callback type for win_sparkle_did_not_find_update_callback() 430 | typedef void (__cdecl *win_sparkle_did_not_find_update_callback_t)(); 431 | 432 | /** 433 | Set callback to be called when the updater did not find an update. 434 | 435 | This is useful in combination with 436 | win_sparkle_check_update_with_ui_and_install() as it allows you to perform 437 | some action after WinSparkle checks for updates. 438 | 439 | @since 0.5 440 | 441 | @see win_sparkle_did_find_update_callback() 442 | @see win_sparkle_check_update_with_ui_and_install() 443 | */ 444 | WIN_SPARKLE_API void __cdecl win_sparkle_set_did_not_find_update_callback(win_sparkle_did_not_find_update_callback_t callback); 445 | 446 | /// Callback type for win_sparkle_update_cancelled_callback() 447 | typedef void (__cdecl *win_sparkle_update_cancelled_callback_t)(); 448 | 449 | /** 450 | Set callback to be called when the user cancels a download. 451 | 452 | This is useful in combination with 453 | win_sparkle_check_update_with_ui_and_install() as it allows you to perform 454 | some action when the installation is interrupted. 455 | 456 | @since 0.5 457 | 458 | @see win_sparkle_check_update_with_ui_and_install() 459 | */ 460 | WIN_SPARKLE_API void __cdecl win_sparkle_set_update_cancelled_callback(win_sparkle_update_cancelled_callback_t callback); 461 | 462 | /// Callback type for win_sparkle_update_skipped_callback() 463 | typedef void(__cdecl* win_sparkle_update_skipped_callback_t)(); 464 | 465 | /** 466 | Set callback to be called when the user skips an update. 467 | 468 | This is useful in combination with 469 | win_sparkle_check_update_with_ui() or similar as it 470 | allows you to perform some action when the update 471 | is skipped. 472 | 473 | @see win_sparkle_check_update_with_ui_and_install() 474 | 475 | @since 0.8 476 | */ 477 | WIN_SPARKLE_API void __cdecl win_sparkle_set_update_skipped_callback(win_sparkle_update_skipped_callback_t callback); 478 | 479 | /// Callback type for win_sparkle_update_postponed_callback() 480 | typedef void(__cdecl* win_sparkle_update_postponed_callback_t)(); 481 | 482 | /** 483 | Set callback to be called when the user postpones an update 484 | ( presses 'remind me later' button). 485 | 486 | This is useful in combination with 487 | win_sparkle_check_update_with_ui() or similar as it 488 | allows you to perform some action when the download 489 | is postponed. 490 | 491 | @see win_sparkle_check_update_with_ui() 492 | 493 | @since 0.8 494 | */ 495 | WIN_SPARKLE_API void __cdecl win_sparkle_set_update_postponed_callback(win_sparkle_update_postponed_callback_t callback); 496 | 497 | /// Callback type for win_sparkle_update_dismissed_callback() 498 | typedef void(__cdecl* win_sparkle_update_dismissed_callback_t)(); 499 | 500 | /** 501 | Set callback to be called when the user dismisses 502 | (closes) update dialog. 503 | 504 | This is useful in combination with 505 | win_sparkle_check_update_with_ui() or similar as it 506 | allows you to perform some action when the update 507 | dialog is closed. 508 | 509 | @see win_sparkle_check_update_with_ui() 510 | 511 | @since 0.8 512 | */ 513 | WIN_SPARKLE_API void __cdecl win_sparkle_set_update_dismissed_callback(win_sparkle_update_dismissed_callback_t callback); 514 | 515 | 516 | /// Callback type for win_sparkle_user_run_installer_callback() 517 | typedef int(__cdecl* win_sparkle_user_run_installer_callback_t)(const wchar_t *); 518 | 519 | /** 520 | Set callback to be called when the update payload is 521 | downloaded and read to be executed.or handled in some 522 | other manner. 523 | 524 | The callback returns: 525 | - 1 if the file was handled by the callback 526 | - 0 if it was not, in which case WinSparkle default handling will take place 527 | - WINSPARKLE_RETURN_ERROR in case of an error 528 | 529 | @since 0.8 530 | */ 531 | WIN_SPARKLE_API void __cdecl win_sparkle_set_user_run_installer_callback(win_sparkle_user_run_installer_callback_t callback); 532 | 533 | //@} 534 | 535 | 536 | /*--------------------------------------------------------------------------* 537 | Manual usage 538 | *--------------------------------------------------------------------------*/ 539 | 540 | /** 541 | @name Manually using WinSparkle 542 | */ 543 | //@{ 544 | 545 | /** 546 | Checks if an update is available, showing progress UI to the user. 547 | 548 | Normally, WinSparkle checks for updates on startup and only shows its UI 549 | when it finds an update. If the application disables this behavior, it 550 | can hook this function to "Check for updates..." menu item. 551 | 552 | When called, background thread is started to check for updates. A small 553 | window is shown to let the user know the progress. If no update is found, 554 | the user is told so. If there is an update, the usual "update available" 555 | window is shown. 556 | 557 | This function returns immediately. 558 | 559 | @note Because this function is intended for manual, user-initiated checks 560 | for updates, it ignores "Skip this version" even if the user checked 561 | it previously. 562 | 563 | @see win_sparkle_check_update_without_ui() 564 | */ 565 | WIN_SPARKLE_API void __cdecl win_sparkle_check_update_with_ui(); 566 | 567 | /** 568 | Checks if an update is available, showing progress UI to the user and 569 | immediately installing the update if one is available. 570 | 571 | This is useful for the case when users should almost always use the 572 | newest version of your software. When called, WinSparkle will check for 573 | updates showing a progress UI to the user. If an update is found the update 574 | prompt will be skipped and the update will be installed immediately. 575 | 576 | If your application expects to do something after checking for updates you 577 | may wish to use win_sparkle_set_did_not_find_update_callback() and 578 | win_sparkle_set_update_cancelled_callback(). 579 | 580 | @since 0.5 581 | 582 | @see win_sparkle_set_did_find_update_callback() 583 | @see win_sparkle_set_update_cancelled_callback() 584 | */ 585 | WIN_SPARKLE_API void __cdecl win_sparkle_check_update_with_ui_and_install(); 586 | 587 | /** 588 | Checks if an update is available. 589 | 590 | No progress UI is shown to the user when checking. If an update is 591 | available, the usual "update available" window is shown; this function 592 | is *not* completely UI-less. 593 | 594 | Use with caution, it usually makes more sense to use the automatic update 595 | checks on interval option or manual check with visible UI. 596 | 597 | This function returns immediately. 598 | 599 | @note This function respects "Skip this version" choice by the user. 600 | 601 | @since 0.4 602 | 603 | @see win_sparkle_check_update_with_ui() 604 | */ 605 | WIN_SPARKLE_API void __cdecl win_sparkle_check_update_without_ui(); 606 | 607 | //@} 608 | 609 | #ifdef __cplusplus 610 | } 611 | #endif 612 | 613 | #endif // _winsparkle_h_ 614 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/x64/Release/WinSparkle.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/x64/Release/WinSparkle.dll -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/x64/Release/WinSparkle.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/x64/Release/WinSparkle.lib -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/WinSparkle-0.8.1/x64/Release/WinSparkle.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/packages/auto_updater_windows/windows/WinSparkle-0.8.1/x64/Release/WinSparkle.pdb -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/auto_updater.cpp: -------------------------------------------------------------------------------- 1 | #include "WinSparkle-0.8.1/include/winsparkle.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace { 12 | // Forward declarations for WinSparkle callbacks 13 | void __onErrorCallback(); 14 | void __onShutdownRequestCallback(); 15 | void __onDidFindUpdateCallback(); 16 | void __onDidNotFindUpdateCallback(); 17 | void __onUpdateCancelledCallback(); 18 | void __onUpdateSkippedCallback(); 19 | void __onUpdatePostponedCallback(); 20 | void __onUpdateDismissedCallback(); 21 | void __onUserRunInstallerCallback(); 22 | 23 | class AutoUpdater { 24 | public: 25 | static AutoUpdater* GetInstance(); 26 | 27 | AutoUpdater(); 28 | 29 | virtual ~AutoUpdater(); 30 | 31 | void AutoUpdater::SetFeedURL(std::string feedURL); 32 | void AutoUpdater::CheckForUpdates(); 33 | void AutoUpdater::CheckForUpdatesWithoutUI(); 34 | void AutoUpdater::SetScheduledCheckInterval(int interval); 35 | 36 | void AutoUpdater::RegisterEventSink( 37 | std::unique_ptr> ptr); 38 | void AutoUpdater::OnWinSparkleEvent(std::string eventName); 39 | 40 | private: 41 | static AutoUpdater* lazySingleton; 42 | std::unique_ptr> event_sink_; 43 | }; 44 | 45 | AutoUpdater* AutoUpdater::lazySingleton = nullptr; 46 | 47 | AutoUpdater* AutoUpdater::GetInstance() { 48 | return lazySingleton; 49 | } 50 | 51 | AutoUpdater::AutoUpdater() { 52 | if (lazySingleton != nullptr) { 53 | throw std::invalid_argument("AutoUpdater has already been initialized"); 54 | } 55 | 56 | lazySingleton = this; 57 | } 58 | 59 | AutoUpdater::~AutoUpdater() {} 60 | 61 | void AutoUpdater::SetFeedURL(std::string feedURL) { 62 | win_sparkle_set_appcast_url(feedURL.c_str()); 63 | win_sparkle_init(); 64 | 65 | win_sparkle_set_error_callback(__onErrorCallback); 66 | win_sparkle_set_shutdown_request_callback(__onShutdownRequestCallback); 67 | win_sparkle_set_did_find_update_callback(__onDidFindUpdateCallback); 68 | win_sparkle_set_did_not_find_update_callback(__onDidNotFindUpdateCallback); 69 | win_sparkle_set_update_cancelled_callback(__onUpdateCancelledCallback); 70 | 71 | // TODO: These will be supported once we update WinSparkle to >0.8.0 72 | // win_sparkle_set_update_skipped_callback(__onUpdateSkippedCallback); 73 | // win_sparkle_set_update_postponed_callback(__onUpdatePostponedCallback); 74 | // win_sparkle_set_update_dismissed_callback(__onUpdateDismissedCallback); 75 | // win_sparkle_set_user_run_installer_callback(__onUserRunInstallerCallback); 76 | } 77 | 78 | void AutoUpdater::CheckForUpdates() { 79 | win_sparkle_check_update_with_ui(); 80 | OnWinSparkleEvent("checking-for-update"); 81 | } 82 | 83 | void AutoUpdater::CheckForUpdatesWithoutUI() { 84 | win_sparkle_check_update_without_ui(); 85 | OnWinSparkleEvent("checking-for-update"); 86 | } 87 | 88 | void AutoUpdater::SetScheduledCheckInterval(int interval) { 89 | win_sparkle_set_update_check_interval(interval); 90 | } 91 | 92 | void AutoUpdater::RegisterEventSink( 93 | std::unique_ptr> ptr) { 94 | event_sink_ = std::move(ptr); 95 | } 96 | 97 | void AutoUpdater::OnWinSparkleEvent(std::string eventName) { 98 | if (event_sink_ == nullptr) 99 | return; 100 | flutter::EncodableMap args = flutter::EncodableMap(); 101 | args[flutter::EncodableValue("type")] = eventName; 102 | if (event_sink_) { 103 | event_sink_->Success(flutter::EncodableValue(args)); 104 | } 105 | } 106 | 107 | void __onErrorCallback() { 108 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 109 | if (autoUpdater == nullptr) 110 | return; 111 | autoUpdater->OnWinSparkleEvent("error"); 112 | } 113 | 114 | void __onShutdownRequestCallback() { 115 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 116 | if (autoUpdater == nullptr) 117 | return; 118 | autoUpdater->OnWinSparkleEvent("before-quit-for-update"); 119 | } 120 | 121 | void __onDidFindUpdateCallback() { 122 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 123 | if (autoUpdater == nullptr) 124 | return; 125 | autoUpdater->OnWinSparkleEvent("update-available"); 126 | } 127 | 128 | void __onDidNotFindUpdateCallback() { 129 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 130 | if (autoUpdater == nullptr) 131 | return; 132 | autoUpdater->OnWinSparkleEvent("update-not-available"); 133 | } 134 | 135 | void __onUpdateCancelledCallback() { 136 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 137 | if (autoUpdater == nullptr) 138 | return; 139 | autoUpdater->OnWinSparkleEvent("updateCancelled"); 140 | } 141 | 142 | void __onUpdateSkippedCallback() { 143 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 144 | if (autoUpdater == nullptr) 145 | return; 146 | autoUpdater->OnWinSparkleEvent("updateSkipped"); 147 | } 148 | 149 | void __onUpdatePostponedCallback() { 150 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 151 | if (autoUpdater == nullptr) 152 | return; 153 | autoUpdater->OnWinSparkleEvent("updatePostponed"); 154 | } 155 | 156 | void __onUpdateDismissedCallback() { 157 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 158 | if (autoUpdater == nullptr) 159 | return; 160 | autoUpdater->OnWinSparkleEvent("updateDismissed"); 161 | } 162 | 163 | void __onUserRunInstallerCallback() { 164 | AutoUpdater* autoUpdater = AutoUpdater::GetInstance(); 165 | if (autoUpdater == nullptr) 166 | return; 167 | autoUpdater->OnWinSparkleEvent("userRunInstaller"); 168 | } 169 | } // namespace 170 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/auto_updater_windows_plugin.cpp: -------------------------------------------------------------------------------- 1 | #include "auto_updater_windows_plugin.h" 2 | 3 | // This must be included before many other Windows headers. 4 | #include 5 | 6 | // #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace auto_updater_windows { 15 | 16 | // static 17 | void AutoUpdaterWindowsPlugin::RegisterWithRegistrar( 18 | flutter::PluginRegistrarWindows* registrar) { 19 | auto channel = 20 | std::make_unique>( 21 | registrar->messenger(), "dev.leanflutter.plugins/auto_updater", 22 | &flutter::StandardMethodCodec::GetInstance()); 23 | 24 | auto plugin = std::make_unique(registrar); 25 | 26 | channel->SetMethodCallHandler( 27 | [plugin_pointer = plugin.get()](const auto& call, auto result) { 28 | plugin_pointer->HandleMethodCall(call, std::move(result)); 29 | }); 30 | auto event_channel = 31 | std::make_unique>( 32 | registrar->messenger(), "dev.leanflutter.plugins/auto_updater_event", 33 | &flutter::StandardMethodCodec::GetInstance()); 34 | auto streamHandler = std::make_unique>( 35 | [plugin_pointer = plugin.get()]( 36 | const flutter::EncodableValue* arguments, 37 | std::unique_ptr>&& events) 38 | -> std::unique_ptr> { 39 | return plugin_pointer->OnListen(arguments, std::move(events)); 40 | }, 41 | [plugin_pointer = plugin.get()](const flutter::EncodableValue* arguments) 42 | -> std::unique_ptr> { 43 | return plugin_pointer->OnCancel(arguments); 44 | }); 45 | event_channel->SetStreamHandler(std::move(streamHandler)); 46 | registrar->AddPlugin(std::move(plugin)); 47 | } 48 | 49 | AutoUpdaterWindowsPlugin::AutoUpdaterWindowsPlugin( 50 | flutter::PluginRegistrarWindows* registrar) { 51 | registrar_ = registrar; 52 | } 53 | 54 | AutoUpdaterWindowsPlugin::~AutoUpdaterWindowsPlugin() {} 55 | 56 | void AutoUpdaterWindowsPlugin::HandleMethodCall( 57 | const flutter::MethodCall& method_call, 58 | std::unique_ptr> result) { 59 | std::string method_name = method_call.method_name(); 60 | 61 | if (method_name.compare("setFeedURL") == 0) { 62 | const flutter::EncodableMap& args = 63 | std::get(*method_call.arguments()); 64 | std::string feedURL = 65 | std::get(args.at(flutter::EncodableValue("feedURL"))); 66 | auto_updater.SetFeedURL(feedURL); 67 | auto_updater.RegisterEventSink(std::move(event_sink_)); 68 | result->Success(flutter::EncodableValue(true)); 69 | 70 | } else if (method_name.compare("checkForUpdates") == 0) { 71 | const flutter::EncodableMap& args = 72 | std::get(*method_call.arguments()); 73 | bool inBackground = 74 | std::get(args.at(flutter::EncodableValue("inBackground"))); 75 | if (inBackground) { 76 | auto_updater.CheckForUpdatesWithoutUI(); 77 | } else { 78 | auto_updater.CheckForUpdates(); 79 | } 80 | result->Success(flutter::EncodableValue(true)); 81 | 82 | } else if (method_name.compare("setScheduledCheckInterval") == 0) { 83 | const flutter::EncodableMap& args = 84 | std::get(*method_call.arguments()); 85 | int interval = std::get(args.at(flutter::EncodableValue("interval"))); 86 | auto_updater.SetScheduledCheckInterval(interval); 87 | result->Success(flutter::EncodableValue(true)); 88 | 89 | } else { 90 | result->NotImplemented(); 91 | } 92 | } 93 | 94 | std::unique_ptr> 95 | AutoUpdaterWindowsPlugin::OnListenInternal( 96 | const flutter::EncodableValue* arguments, 97 | std::unique_ptr>&& events) { 98 | event_sink_ = std::move(events); 99 | return nullptr; 100 | } 101 | 102 | std::unique_ptr> 103 | AutoUpdaterWindowsPlugin::OnCancelInternal( 104 | const flutter::EncodableValue* arguments) { 105 | event_sink_ = nullptr; 106 | return nullptr; 107 | } 108 | } // namespace auto_updater_windows 109 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/auto_updater_windows_plugin.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_PLUGIN_AUTO_UPDATER_WINDOWS_PLUGIN_H_ 2 | #define FLUTTER_PLUGIN_AUTO_UPDATER_WINDOWS_PLUGIN_H_ 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include "auto_updater.cpp" 12 | 13 | namespace auto_updater_windows { 14 | 15 | class AutoUpdaterWindowsPlugin 16 | : public flutter::Plugin, 17 | flutter::StreamHandler { 18 | private: 19 | flutter::PluginRegistrarWindows* registrar_; 20 | std::unique_ptr> event_sink_; 21 | AutoUpdater auto_updater = AutoUpdater(); 22 | 23 | public: 24 | static void RegisterWithRegistrar(flutter::PluginRegistrarWindows* registrar); 25 | 26 | AutoUpdaterWindowsPlugin(flutter::PluginRegistrarWindows* registrar); 27 | 28 | virtual ~AutoUpdaterWindowsPlugin(); 29 | 30 | // Disallow copy and assign. 31 | AutoUpdaterWindowsPlugin(const AutoUpdaterWindowsPlugin&) = delete; 32 | AutoUpdaterWindowsPlugin& operator=(const AutoUpdaterWindowsPlugin&) = delete; 33 | 34 | // Called when a method is called on this plugin's channel from Dart. 35 | void HandleMethodCall( 36 | const flutter::MethodCall& method_call, 37 | std::unique_ptr> result); 38 | 39 | std::unique_ptr> OnListenInternal( 40 | const flutter::EncodableValue* arguments, 41 | std::unique_ptr>&& events) override; 42 | 43 | std::unique_ptr> OnCancelInternal( 44 | const flutter::EncodableValue* arguments) override; 45 | }; 46 | 47 | } // namespace auto_updater_windows 48 | 49 | #endif // FLUTTER_PLUGIN_AUTO_UPDATER_WINDOWS_PLUGIN_H_ 50 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/auto_updater_windows_plugin_c_api.cpp: -------------------------------------------------------------------------------- 1 | #include "include/auto_updater_windows/auto_updater_windows_plugin_c_api.h" 2 | 3 | #include 4 | 5 | #include "auto_updater_windows_plugin.h" 6 | 7 | void AutoUpdaterWindowsPluginCApiRegisterWithRegistrar( 8 | FlutterDesktopPluginRegistrarRef registrar) { 9 | auto_updater_windows::AutoUpdaterWindowsPlugin::RegisterWithRegistrar( 10 | flutter::PluginRegistrarManager::GetInstance() 11 | ->GetRegistrar(registrar)); 12 | } 13 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/include/auto_updater_windows/auto_updater_windows_plugin_c_api.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_PLUGIN_AUTO_UPDATER_WINDOWS_PLUGIN_C_API_H_ 2 | #define FLUTTER_PLUGIN_AUTO_UPDATER_WINDOWS_PLUGIN_C_API_H_ 3 | 4 | #include 5 | 6 | #ifdef FLUTTER_PLUGIN_IMPL 7 | #define FLUTTER_PLUGIN_EXPORT __declspec(dllexport) 8 | #else 9 | #define FLUTTER_PLUGIN_EXPORT __declspec(dllimport) 10 | #endif 11 | 12 | #if defined(__cplusplus) 13 | extern "C" { 14 | #endif 15 | 16 | FLUTTER_PLUGIN_EXPORT void AutoUpdaterWindowsPluginCApiRegisterWithRegistrar( 17 | FlutterDesktopPluginRegistrarRef registrar); 18 | 19 | #if defined(__cplusplus) 20 | } // extern "C" 21 | #endif 22 | 23 | #endif // FLUTTER_PLUGIN_AUTO_UPDATER_WINDOWS_PLUGIN_C_API_H_ 24 | -------------------------------------------------------------------------------- /packages/auto_updater_windows/windows/test/auto_updater_windows_plugin_test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include "auto_updater_windows_plugin.h" 12 | 13 | namespace auto_updater_windows { 14 | namespace test { 15 | 16 | namespace { 17 | 18 | using flutter::EncodableMap; 19 | using flutter::EncodableValue; 20 | using flutter::MethodCall; 21 | using flutter::MethodResultFunctions; 22 | 23 | } // namespace 24 | 25 | TEST(AutoUpdaterWindowsPlugin, GetPlatformVersion) { 26 | AutoUpdaterWindowsPlugin plugin; 27 | // Save the reply value from the success callback. 28 | std::string result_string; 29 | plugin.HandleMethodCall( 30 | MethodCall("getPlatformVersion", std::make_unique()), 31 | std::make_unique>( 32 | [&result_string](const EncodableValue* result) { 33 | result_string = std::get(*result); 34 | }, 35 | nullptr, nullptr)); 36 | 37 | // Since the exact string varies by host, just ensure that it's a string 38 | // with the expected format. 39 | EXPECT_TRUE(result_string.rfind("Windows ", 0) == 0); 40 | } 41 | 42 | } // namespace test 43 | } // namespace auto_updater_windows 44 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: auto_updater_workspace 2 | homepage: https://github.com/leanflutter/auto_updater 3 | publish_to: none 4 | 5 | environment: 6 | sdk: ">=3.0.0 <4.0.0" 7 | 8 | dev_dependencies: 9 | melos: ^6.2.0 10 | -------------------------------------------------------------------------------- /screenshots/sparkle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/screenshots/sparkle.png -------------------------------------------------------------------------------- /screenshots/winsparkle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leanflutter/auto_updater/93fee1d1726e016359c6d621c9612f42a1c6ce38/screenshots/winsparkle.png --------------------------------------------------------------------------------