feat: v0.12.4 —— 安装包工作流扩到 Windows / macOS
安装包 / Linux aarch64 (push) Canceled after 0s
安装包 / Linux x86_64 (push) Canceled after 0s
安装包 / Windows x86_64 (push) Canceled after 0s
安装包 / macOS arm64 (Apple Silicon) (push) Canceled after 0s
安装包 / macOS x86_64 (Intel) (push) Canceled after 0s
安装包 / 发布到 Release (push) Canceled after 0s
安装包 / Linux aarch64 (push) Canceled after 0s
安装包 / Linux x86_64 (push) Canceled after 0s
安装包 / Windows x86_64 (push) Canceled after 0s
安装包 / macOS arm64 (Apple Silicon) (push) Canceled after 0s
安装包 / macOS x86_64 (Intel) (push) Canceled after 0s
安装包 / 发布到 Release (push) Canceled after 0s
- 工作流改名 .github/workflows/packages.yml,新增 Windows 和两个 macOS job - Windows:windeployqt 收运行库,NSIS 按当前用户装到 LOCALAPPDATA(免管理员), 关联 .md、「打开方式」注册、开始菜单/桌面快捷方式、卸载项,另出便携 zip; 安装包未签名 - macOS arm64:Homebrew Qt 5(原生 arm64,不依赖 Rosetta),macdeployqt 后把 Homebrew 的 libpng/freetype 等依赖收进 app,再 ad-hoc 签名、打 dmg - macOS x86_64:Qt 5.15.2 官方二进制 + macos-15-intel runner,同样签名打 dmg - Release 汇总所有平台产物并生成 SHA256SUMS;某个平台失败不影响其它平台 - README 写清三平台产物、未签名打开方式、.md 关联和发版方式
This commit is contained in:
@@ -1,161 +0,0 @@
|
|||||||
name: Linux 安装包
|
|
||||||
|
|
||||||
# 仓库本身在 Gitea,这个工作流是给 GitHub 镜像用的:
|
|
||||||
# 推送、打 tag(v*)、手动触发、PR 检查时编译并打出 .deb / .rpm。
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main, master]
|
|
||||||
tags: ["v*"]
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
publish:
|
|
||||||
description: "发布 Release(用 v<版本> 当 tag,不必先打 tag)"
|
|
||||||
type: boolean
|
|
||||||
default: false
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: packages-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
package:
|
|
||||||
name: ${{ matrix.arch }} · deb + rpm
|
|
||||||
runs-on: ${{ matrix.runs-on }}
|
|
||||||
# ARM runner 只有公共仓库(或自建 arm64 runner)才有;私有仓库里这一步失败
|
|
||||||
# 不算整体失败,x86_64 的包照常产出。
|
|
||||||
continue-on-error: ${{ matrix.optional }}
|
|
||||||
timeout-minutes: 30
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
- arch: x86_64
|
|
||||||
runs-on: ubuntu-22.04
|
|
||||||
deb_arch: amd64
|
|
||||||
rpm_arch: x86_64
|
|
||||||
optional: false
|
|
||||||
- arch: aarch64
|
|
||||||
runs-on: ubuntu-24.04-arm
|
|
||||||
deb_arch: arm64
|
|
||||||
rpm_arch: aarch64
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: 检出代码
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 安装构建依赖
|
|
||||||
run: |
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install -y --no-install-recommends \
|
|
||||||
build-essential file \
|
|
||||||
qtbase5-dev qtbase5-dev-tools qt5-qmake \
|
|
||||||
rpm dpkg-dev
|
|
||||||
|
|
||||||
- name: 读取版本号
|
|
||||||
id: meta
|
|
||||||
run: |
|
|
||||||
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
|
||||||
if [ -z "$version" ]; then
|
|
||||||
echo "VoiletMark.pro 里没有 VERSION" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: 编译
|
|
||||||
run: |
|
|
||||||
qmake_bin=$(command -v qmake-qt5 || command -v qmake || true)
|
|
||||||
if [ -z "$qmake_bin" ]; then
|
|
||||||
echo "找不到 qmake(确认装了 qtbase5-dev / qt5-qmake)" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
"$qmake_bin" -v
|
|
||||||
mkdir -p build
|
|
||||||
cd build
|
|
||||||
"$qmake_bin" ../VoiletMark.pro PREFIX=/usr CONFIG+=release
|
|
||||||
make -j"$(nproc)"
|
|
||||||
make install INSTALL_ROOT="$PWD/stage"
|
|
||||||
find stage -type f | sort
|
|
||||||
|
|
||||||
- name: 打 .deb
|
|
||||||
run: |
|
|
||||||
./packaging/build-deb.sh build/stage "${{ steps.meta.outputs.version }}" "${{ matrix.deb_arch }}" dist
|
|
||||||
|
|
||||||
- name: 打 .rpm
|
|
||||||
run: |
|
|
||||||
./packaging/build-rpm.sh build/stage "${{ steps.meta.outputs.version }}" "${{ matrix.rpm_arch }}" dist
|
|
||||||
|
|
||||||
- name: 检查产物
|
|
||||||
run: |
|
|
||||||
ls -lh dist
|
|
||||||
dpkg-deb -I dist/*.deb
|
|
||||||
rpm -qpi dist/*.rpm
|
|
||||||
rpm -qpl dist/*.rpm
|
|
||||||
|
|
||||||
- name: 上传构建产物
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: voiletmark-${{ matrix.arch }}
|
|
||||||
path: dist/*
|
|
||||||
if-no-files-found: error
|
|
||||||
|
|
||||||
release:
|
|
||||||
name: 发布到 Release
|
|
||||||
needs: package
|
|
||||||
# 只有两种情况发 Release:
|
|
||||||
# 1. 推了 v* tag
|
|
||||||
# 2. 手动 Run workflow 并勾上 publish
|
|
||||||
# 普通推送(main / PR)只会留下 artifact,这一步显示 skipped 是正常的。
|
|
||||||
# 用 always() 是为了 ARM 那个 job 失败(拿不到 arm runner)时这里照常收尾,
|
|
||||||
# 下面会检查 x86_64 的包在不在,缺了就不发。
|
|
||||||
if: >-
|
|
||||||
always() && (
|
|
||||||
startsWith(github.ref, 'refs/tags/') ||
|
|
||||||
(github.event_name == 'workflow_dispatch' && inputs.publish)
|
|
||||||
)
|
|
||||||
runs-on: ubuntu-24.04
|
|
||||||
timeout-minutes: 10
|
|
||||||
steps:
|
|
||||||
- name: 检出代码
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: 读取版本号
|
|
||||||
id: meta
|
|
||||||
run: |
|
|
||||||
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
|
||||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
||||||
|
|
||||||
- name: 下载所有产物
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
path: dist
|
|
||||||
merge-multiple: true
|
|
||||||
|
|
||||||
- name: 确认 x86_64 的包存在
|
|
||||||
run: |
|
|
||||||
ls -lh dist
|
|
||||||
test -n "$(ls dist/*amd64.deb 2>/dev/null)" || {
|
|
||||||
echo "没有 x86_64 的 deb,不发布" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
- name: 生成 SHA256SUMS
|
|
||||||
run: |
|
|
||||||
cd dist
|
|
||||||
sha256sum ./*.deb ./*.rpm > SHA256SUMS
|
|
||||||
cat SHA256SUMS
|
|
||||||
|
|
||||||
- name: 挂到 Release
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
with:
|
|
||||||
# 打 tag 时用那个 tag;手动发布时用 v<版本>(不存在就按当前提交新建)
|
|
||||||
tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('v{0}', steps.meta.outputs.version) }}
|
|
||||||
target_commitish: ${{ github.sha }}
|
|
||||||
name: VoiletMark ${{ steps.meta.outputs.version }}
|
|
||||||
files: dist/*
|
|
||||||
generate_release_notes: true
|
|
||||||
fail_on_unmatched_files: true
|
|
||||||
@@ -0,0 +1,366 @@
|
|||||||
|
name: 安装包
|
||||||
|
|
||||||
|
# Gitea 不跑这个工作流;同步到 GitHub 后,这里编译并打出:
|
||||||
|
# Linux deb / rpm(x86_64、aarch64)
|
||||||
|
# Windows 安装包(关联 .md)+ 便携 zip
|
||||||
|
# macOS arm64 / x86_64 两个 dmg(未签名,不是公证版)
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, master]
|
||||||
|
tags: ["v*"]
|
||||||
|
pull_request:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
publish:
|
||||||
|
description: "发布 Release(用 v<版本> 当 tag,不必先打 tag)"
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: packages-${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
|
env:
|
||||||
|
QT_VERSION: "5.15.2"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
linux:
|
||||||
|
name: Linux ${{ matrix.arch }}
|
||||||
|
runs-on: ${{ matrix.runs-on }}
|
||||||
|
continue-on-error: ${{ matrix.optional }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: x86_64
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
deb_arch: amd64
|
||||||
|
rpm_arch: x86_64
|
||||||
|
optional: false
|
||||||
|
- arch: aarch64
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
deb_arch: arm64
|
||||||
|
rpm_arch: aarch64
|
||||||
|
optional: true
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 安装构建依赖
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y --no-install-recommends \
|
||||||
|
build-essential file \
|
||||||
|
qtbase5-dev qtbase5-dev-tools qt5-qmake \
|
||||||
|
rpm dpkg-dev
|
||||||
|
|
||||||
|
- name: 读取版本号
|
||||||
|
id: meta
|
||||||
|
run: |
|
||||||
|
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
echo "VoiletMark.pro 里没有 VERSION" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: 编译
|
||||||
|
run: |
|
||||||
|
qmake_bin=$(command -v qmake-qt5 || command -v qmake || true)
|
||||||
|
if [ -z "$qmake_bin" ]; then
|
||||||
|
echo "找不到 qmake(确认装了 qtbase5-dev / qt5-qmake)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
"$qmake_bin" -v
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
"$qmake_bin" ../VoiletMark.pro PREFIX=/usr CONFIG+=release
|
||||||
|
make -j"$(nproc)"
|
||||||
|
make install INSTALL_ROOT="$PWD/stage"
|
||||||
|
find stage -type f | sort
|
||||||
|
|
||||||
|
- name: 打 .deb
|
||||||
|
run: ./packaging/build-deb.sh build/stage "${{ steps.meta.outputs.version }}" "${{ matrix.deb_arch }}" dist
|
||||||
|
|
||||||
|
- name: 打 .rpm
|
||||||
|
run: ./packaging/build-rpm.sh build/stage "${{ steps.meta.outputs.version }}" "${{ matrix.rpm_arch }}" dist
|
||||||
|
|
||||||
|
- name: 检查产物
|
||||||
|
run: |
|
||||||
|
ls -lh dist
|
||||||
|
dpkg-deb -I dist/*.deb
|
||||||
|
rpm -qpi dist/*.rpm
|
||||||
|
|
||||||
|
- name: 上传产物
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: voiletmark-linux-${{ matrix.arch }}
|
||||||
|
path: dist/*
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
windows:
|
||||||
|
name: Windows x86_64
|
||||||
|
runs-on: windows-2022
|
||||||
|
timeout-minutes: 40
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 准备 MSVC 环境
|
||||||
|
uses: ilammy/msvc-dev-cmd@v1
|
||||||
|
with:
|
||||||
|
arch: x64
|
||||||
|
|
||||||
|
- name: 安装 Qt ${{ env.QT_VERSION }}
|
||||||
|
uses: jurplel/install-qt-action@v4
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
arch: win64_msvc2019_64
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: 编译并收集 Qt 依赖
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
echo "VoiletMark.pro 里没有 VERSION" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "APP_VERSION=$version" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
qmake ../VoiletMark.pro CONFIG+=release
|
||||||
|
nmake release || nmake
|
||||||
|
if [ -f release/VoiletMark.exe ]; then
|
||||||
|
exe=release/VoiletMark.exe
|
||||||
|
else
|
||||||
|
exe=$(find . -name VoiletMark.exe | head -n1)
|
||||||
|
fi
|
||||||
|
if [ -z "$exe" ]; then
|
||||||
|
echo "没找到 VoiletMark.exe" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
mkdir -p ../deploy
|
||||||
|
cp "$exe" ../deploy/VoiletMark.exe
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
windeployqt --release --no-translations --compiler-runtime deploy/VoiletMark.exe
|
||||||
|
find deploy -maxdepth 1 -type f | sort
|
||||||
|
|
||||||
|
- name: 打 NSIS 安装包(关联 .md)
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
mkdir -p dist
|
||||||
|
|
||||||
|
makensis='/c/Program Files (x86)/NSIS/makensis.exe'
|
||||||
|
if [ ! -x "$makensis" ]; then
|
||||||
|
makensis=$(find '/c/Program Files (x86)' '/c/Program Files' -maxdepth 3 -iname 'makensis.exe' 2>/dev/null | head -n1)
|
||||||
|
fi
|
||||||
|
if [ -z "$makensis" ]; then
|
||||||
|
choco install nsis -y --no-progress
|
||||||
|
makensis=$(find '/c/Program Files (x86)' '/c/Program Files' -maxdepth 3 -iname 'makensis.exe' 2>/dev/null | head -n1)
|
||||||
|
fi
|
||||||
|
if [ -z "$makensis" ]; then
|
||||||
|
echo "找不到 makensis(NSIS)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
output=$(cygpath -w "$PWD/dist/VoiletMark-$APP_VERSION-win64-setup.exe")
|
||||||
|
deploy=$(cygpath -w "$PWD/deploy")
|
||||||
|
icon=$(cygpath -w "$PWD/packaging/voiletmark.ico")
|
||||||
|
script=$(cygpath -w "$PWD/packaging/windows/installer.nsi")
|
||||||
|
|
||||||
|
"$makensis" \
|
||||||
|
"/DAPP_VERSION=$APP_VERSION" \
|
||||||
|
"/DDEPLOY_DIR=$deploy" \
|
||||||
|
"/DICON_FILE=$icon" \
|
||||||
|
"/DOUTPUT_FILE=$output" \
|
||||||
|
"$script"
|
||||||
|
|
||||||
|
ls -lh dist
|
||||||
|
|
||||||
|
- name: 便携版 zip
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Compress-Archive -Path deploy/* -DestinationPath "dist/VoiletMark-$env:APP_VERSION-win64-portable.zip"
|
||||||
|
Get-ChildItem dist | Select-Object Name, Length
|
||||||
|
|
||||||
|
- name: 上传产物
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: voiletmark-windows-x86_64
|
||||||
|
path: dist/*
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
macos-arm64:
|
||||||
|
name: macOS arm64 (Apple Silicon)
|
||||||
|
runs-on: macos-15
|
||||||
|
timeout-minutes: 50
|
||||||
|
env:
|
||||||
|
HOMEBREW_NO_AUTO_UPDATE: "1"
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 安装 Qt 5(Homebrew,原生 arm64)
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
brew install qt@5
|
||||||
|
qt_prefix=$(brew --prefix qt@5)
|
||||||
|
echo "QT_PREFIX=$qt_prefix" >> "$GITHUB_ENV"
|
||||||
|
"$qt_prefix/bin/qmake" -v
|
||||||
|
|
||||||
|
- name: 编译并打包 Qt 框架
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
echo "VoiletMark.pro 里没有 VERSION" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "APP_VERSION=$version" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
"$QT_PREFIX/bin/qmake" ../VoiletMark.pro CONFIG+=release
|
||||||
|
make -j"$(sysctl -n hw.ncpu)"
|
||||||
|
|
||||||
|
file VoiletMark.app/Contents/MacOS/VoiletMark | tee /tmp/arch.txt
|
||||||
|
grep -q arm64 /tmp/arch.txt
|
||||||
|
|
||||||
|
"$QT_PREFIX/bin/macdeployqt" VoiletMark.app -always-overwrite
|
||||||
|
otool -L VoiletMark.app/Contents/MacOS/VoiletMark | head -30
|
||||||
|
|
||||||
|
- name: 收 Homebrew 依赖 + ad-hoc 签名
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
./packaging/macos/bundle-libs.sh build/VoiletMark.app
|
||||||
|
xattr -cr build/VoiletMark.app
|
||||||
|
codesign --force --deep --sign - build/VoiletMark.app
|
||||||
|
codesign --verify --deep --strict build/VoiletMark.app
|
||||||
|
|
||||||
|
- name: 打 dmg
|
||||||
|
run: ./packaging/macos/build-dmg.sh build/VoiletMark.app "$APP_VERSION" arm64 dist
|
||||||
|
|
||||||
|
- name: 上传产物
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: voiletmark-macos-arm64
|
||||||
|
path: dist/*
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
macos-x86_64:
|
||||||
|
name: macOS x86_64 (Intel)
|
||||||
|
# Intel 的 GitHub runner;拿不到这个 runner 时这一步会失败,不影响其它产物
|
||||||
|
runs-on: macos-15-intel
|
||||||
|
timeout-minutes: 40
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 安装 Qt ${{ env.QT_VERSION }}
|
||||||
|
uses: jurplel/install-qt-action@v4
|
||||||
|
with:
|
||||||
|
version: ${{ env.QT_VERSION }}
|
||||||
|
arch: clang_64
|
||||||
|
cache: true
|
||||||
|
|
||||||
|
- name: 编译并打包 Qt 框架
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
||||||
|
if [ -z "$version" ]; then
|
||||||
|
echo "VoiletMark.pro 里没有 VERSION" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "APP_VERSION=$version" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
|
mkdir -p build
|
||||||
|
cd build
|
||||||
|
qmake ../VoiletMark.pro CONFIG+=release
|
||||||
|
make -j"$(sysctl -n hw.ncpu)"
|
||||||
|
|
||||||
|
file VoiletMark.app/Contents/MacOS/VoiletMark | tee /tmp/arch.txt
|
||||||
|
grep -q x86_64 /tmp/arch.txt
|
||||||
|
|
||||||
|
macdeployqt VoiletMark.app -always-overwrite
|
||||||
|
|
||||||
|
- name: 收依赖 + ad-hoc 签名
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
./packaging/macos/bundle-libs.sh build/VoiletMark.app
|
||||||
|
xattr -cr build/VoiletMark.app
|
||||||
|
codesign --force --deep --sign - build/VoiletMark.app
|
||||||
|
codesign --verify --deep --strict build/VoiletMark.app
|
||||||
|
|
||||||
|
- name: 打 dmg
|
||||||
|
run: ./packaging/macos/build-dmg.sh build/VoiletMark.app "$APP_VERSION" x86_64 dist
|
||||||
|
|
||||||
|
- name: 上传产物
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: voiletmark-macos-x86_64
|
||||||
|
path: dist/*
|
||||||
|
if-no-files-found: error
|
||||||
|
|
||||||
|
release:
|
||||||
|
name: 发布到 Release
|
||||||
|
needs: [linux, windows, macos-arm64, macos-x86_64]
|
||||||
|
# 打 tag 或手动勾 publish 才发;普通推送/PR 只留 artifact。
|
||||||
|
# always() 是为了某个平台失败时其它产物还能发出来。
|
||||||
|
if: >-
|
||||||
|
always() && (
|
||||||
|
startsWith(github.ref, 'refs/tags/') ||
|
||||||
|
(github.event_name == 'workflow_dispatch' && inputs.publish)
|
||||||
|
)
|
||||||
|
runs-on: ubuntu-24.04
|
||||||
|
timeout-minutes: 10
|
||||||
|
steps:
|
||||||
|
- name: 检出代码
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: 读取版本号
|
||||||
|
id: meta
|
||||||
|
run: |
|
||||||
|
version=$(sed -n 's/^VERSION[[:space:]]*=[[:space:]]*//p' VoiletMark.pro | head -n1 | tr -d '[:space:]')
|
||||||
|
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: 下载所有产物
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
path: dist
|
||||||
|
merge-multiple: true
|
||||||
|
|
||||||
|
- name: 检查产物
|
||||||
|
run: |
|
||||||
|
ls -lh dist
|
||||||
|
count=$(find dist -maxdepth 1 -type f | wc -l)
|
||||||
|
if [ "$count" -eq 0 ]; then
|
||||||
|
echo "一个安装包都没有,不发布" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: 生成 SHA256SUMS
|
||||||
|
run: |
|
||||||
|
cd dist
|
||||||
|
find . -maxdepth 1 -type f ! -name SHA256SUMS -printf '%f\n' | sort > /tmp/files.txt
|
||||||
|
xargs sha256sum < /tmp/files.txt > SHA256SUMS
|
||||||
|
cat SHA256SUMS
|
||||||
|
|
||||||
|
- name: 挂到 Release
|
||||||
|
uses: softprops/action-gh-release@v2
|
||||||
|
with:
|
||||||
|
# 打 tag 时用那个 tag;手动发布时用 v<版本>(不存在就按当前提交新建)
|
||||||
|
tag_name: ${{ startsWith(github.ref, 'refs/tags/') && github.ref_name || format('v{0}', steps.meta.outputs.version) }}
|
||||||
|
target_commitish: ${{ github.sha }}
|
||||||
|
name: VoiletMark ${{ steps.meta.outputs.version }}
|
||||||
|
files: dist/*
|
||||||
|
generate_release_notes: true
|
||||||
|
fail_on_unmatched_files: true
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。
|
一个轻量的跨平台 Markdown 编辑器,基于 **Qt 5 / C++17** 构建。
|
||||||
|
|
||||||
当前版本 **0.12.3**。
|
当前版本 **0.12.4**。
|
||||||
|
|
||||||
## 界面
|
## 界面
|
||||||
|
|
||||||
@@ -205,24 +205,39 @@ make -C build install INSTALL_ROOT=/tmp/pkg # 打包用,装到 /tmp/pkg/usr/lo
|
|||||||
会一起装上可执行文件、`voiletmark.desktop` 和 256×256 图标,
|
会一起装上可执行文件、`voiletmark.desktop` 和 256×256 图标,
|
||||||
装完就能在应用菜单里搜到 VoiletMark。
|
装完就能在应用菜单里搜到 VoiletMark。
|
||||||
|
|
||||||
## 打包(Linux)
|
## 打包(安装包)
|
||||||
|
|
||||||
`.github/workflows/linux-packages.yml` 是给 GitHub 镜像用的:它会编译代码并打出
|
`.github/workflows/packages.yml` 是给 GitHub 镜像用的(Gitea 上不跑):推代码、打 tag、
|
||||||
`.deb` 和 `.rpm`(本仓库在 Gitea 上,Gitea 不跑这个工作流)。
|
PR 或手动运行时编译,并打出下面这些安装包。
|
||||||
|
|
||||||
- 触发方式:推送到 `main`、打 tag(`v*`)、手动 **Actions → Linux 安装包 → Run workflow**、PR 检查
|
| 平台 | runner | 产物 |
|
||||||
- x86_64(`ubuntu-22.04`):`voiletmark_<版本>_amd64.deb` 和 `voiletmark-<版本>-1.x86_64.rpm`
|
| --- | --- | --- |
|
||||||
- aarch64(`ubuntu-24.04-arm`):`..._arm64.deb` 和 `...aarch64.rpm`。这个 runner 公共仓库才有;
|
| Linux x86_64 | `ubuntu-22.04` | `voiletmark_<版本>_amd64.deb`、`voiletmark-<版本>-1.x86_64.rpm` |
|
||||||
私有仓库里 ARM 那一步设成了 `continue-on-error`,失败不会影响 x86_64 的包,
|
| Linux aarch64 | `ubuntu-24.04-arm` | `..._arm64.deb`、`...aarch64.rpm` |
|
||||||
也可以把 `runs-on` 换成自建的 arm64 runner
|
| Windows x86_64 | `windows-2022` | `VoiletMark-<版本>-win64-setup.exe`、`...-win64-portable.zip` |
|
||||||
- 每次构建都会上传 artifact
|
| macOS arm64 | `macos-15` | `VoiletMark-<版本>-macos-arm64.dmg` |
|
||||||
- 发 Release 的两种方式:
|
| macOS x86_64 | `macos-15-intel` | `VoiletMark-<版本>-macos-x86_64.dmg` |
|
||||||
- 打 tag:`git tag v0.12.3 && git push origin v0.12.3`(同步到 GitHub 时把 tag 一起推过去)
|
|
||||||
- 不打 tag:**Actions → Linux 安装包 → Run workflow**,把 **publish** 勾上,
|
|
||||||
它会用 `v<版本>` 当 tag(不存在就按当前提交新建)并发出 Release
|
|
||||||
- 普通推送到 main / PR 只上传 artifact,不发 Release——「发布到 Release」显示 skipped 是正常的
|
|
||||||
|
|
||||||
本地打包(版本号从 `VoiletMark.pro` 里取):
|
说明:
|
||||||
|
|
||||||
|
- Windows 安装包按当前用户装到 `%LOCALAPPDATA%\Programs\VoiletMark`,不需要管理员权限;
|
||||||
|
会把 `.md` 关联到 VoiletMark,卸载时清理快捷方式、注册表和(仍指向本程序的)关联
|
||||||
|
- macOS 的 arm64 包是**原生**的,不依赖 Rosetta;Intel 包在 `macos-15-intel` 上用 Qt 5.15.2 官方二进制打
|
||||||
|
- 两个 dmg 都没有签名 / 公证:第一次打开要右键 →「打开」,或去「系统设置 → 隐私与安全性」点「仍要打开」
|
||||||
|
- Windows 安装包也没签名,SmartScreen 会拦一下(更多信息 → 仍要运行)
|
||||||
|
- 如果 .md 在资源管理器里还指向别的程序:右键 →「打开方式」→「选择其他应用」→ 勾选用 VoiletMark 打开(Win8 之后 UserChoice 不允许安装包直接改)
|
||||||
|
- Linux ARM 和 macOS Intel 的 runner 不是所有仓库都有;拿不到时那几个 job 会失败,不影响其它产物
|
||||||
|
- 某个平台失败时 Release 仍会带上其它平台成功的包
|
||||||
|
|
||||||
|
### 发 Release
|
||||||
|
|
||||||
|
- 打 tag:`git tag v0.12.4 && git push origin v0.12.4`(同步到 GitHub 时把 tag 一起推过去)
|
||||||
|
- 不打 tag:**Actions → 安装包 → Run workflow**,勾上 **publish**,会用 `v<版本>` 当 tag
|
||||||
|
- 普通推送 / PR 只上传 artifact,不发 Release——「发布到 Release」显示 skipped 是正常的
|
||||||
|
|
||||||
|
### 本地打包(Linux)
|
||||||
|
|
||||||
|
版本号从 `VoiletMark.pro` 里取:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p build && cd build
|
mkdir -p build && cd build
|
||||||
@@ -243,6 +258,7 @@ sudo dnf install ./voiletmark-*.x86_64.rpm
|
|||||||
|
|
||||||
打 rpm 需要 `rpmbuild`(Ubuntu 上 `apt install rpm`)。rpm 的 `License` 字段现在写的是
|
打 rpm 需要 `rpmbuild`(Ubuntu 上 `apt install rpm`)。rpm 的 `License` 字段现在写的是
|
||||||
`Proprietary`(仓库里还没放 LICENSE 文件),要换许可证改 `packaging/build-rpm.sh` 里那一行即可。
|
`Proprietary`(仓库里还没放 LICENSE 文件),要换许可证改 `packaging/build-rpm.sh` 里那一行即可。
|
||||||
|
Windows / macOS 的安装包建议直接用 CI 打(本地需要 NSIS、Xcode / Homebrew Qt),这里不再展开。
|
||||||
|
|
||||||
## 图标
|
## 图标
|
||||||
|
|
||||||
@@ -304,8 +320,8 @@ src/
|
|||||||
logo.png 图标源文件
|
logo.png 图标源文件
|
||||||
resources.qrc 窗口图标与翻译资源
|
resources.qrc 窗口图标与翻译资源
|
||||||
translations/ 中英文翻译(.ts / .qm)
|
translations/ 中英文翻译(.ts / .qm)
|
||||||
packaging/ 图标生成、.desktop、deb / rpm 打包脚本
|
packaging/ 图标、.desktop、deb/rpm、NSIS、macOS dmg 打包脚本
|
||||||
.github/workflows/ GitHub Actions:编译 + 打 deb / rpm
|
.github/workflows/ GitHub Actions:编译 + 打三平台安装包
|
||||||
```
|
```
|
||||||
|
|
||||||
## 下一版计划
|
## 下一版计划
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
TEMPLATE = app
|
TEMPLATE = app
|
||||||
TARGET = VoiletMark
|
TARGET = VoiletMark
|
||||||
VERSION = 0.12.3
|
VERSION = 0.12.4
|
||||||
|
|
||||||
QT += core gui widgets
|
QT += core gui widgets
|
||||||
|
|
||||||
@@ -16,6 +16,8 @@ RESOURCES += resources.qrc
|
|||||||
# 各平台的可执行文件图标
|
# 各平台的可执行文件图标
|
||||||
win32: RC_ICONS = packaging/voiletmark.ico
|
win32: RC_ICONS = packaging/voiletmark.ico
|
||||||
macx: ICON = packaging/voiletmark.icns
|
macx: ICON = packaging/voiletmark.icns
|
||||||
|
macx: QMAKE_TARGET_BUNDLE_PREFIX = com.linuxacme
|
||||||
|
macx: QMAKE_TARGET_DESCRIPTION = "VoiletMark Markdown Editor"
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
src/main.cpp \
|
src/main.cpp \
|
||||||
|
|||||||
Executable
+25
@@ -0,0 +1,25 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# 用 hdiutil 打一个拖拽式 dmg(里面带 /Applications 快捷方式)
|
||||||
|
# 用法: build-dmg.sh <VoiletMark.app> <版本> <arm64|x86_64> <输出目录>
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
app=$1
|
||||||
|
version=$2
|
||||||
|
arch=$3
|
||||||
|
out=$4
|
||||||
|
|
||||||
|
if [ ! -d "$app" ]; then
|
||||||
|
echo "找不到 $app" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$out"
|
||||||
|
stage=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$stage"' EXIT
|
||||||
|
|
||||||
|
ditto "$app" "$stage/VoiletMark.app"
|
||||||
|
ln -s /Applications "$stage/Applications"
|
||||||
|
|
||||||
|
name="VoiletMark-$version-macos-$arch.dmg"
|
||||||
|
hdiutil create -volname "VoiletMark $version" -srcfolder "$stage" -ov -format UDZO "$out/$name" >/dev/null
|
||||||
|
echo "已生成 $out/$name"
|
||||||
Executable
+46
@@ -0,0 +1,46 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# 把 .app 里引用到的 Homebrew 动态库收进 Contents/Frameworks,并把引用改成包内相对路径。
|
||||||
|
# Homebrew 的 Qt 会链到 /opt/homebrew 下的 libpng / freetype 等,macdeployqt 不会带它们。
|
||||||
|
# 用法: bundle-libs.sh <VoiletMark.app>
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
app=$1
|
||||||
|
if [ ! -d "$app" ]; then
|
||||||
|
echo "找不到 $app" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
frameworks=$app/Contents/Frameworks
|
||||||
|
mkdir -p "$frameworks"
|
||||||
|
|
||||||
|
round=0
|
||||||
|
while [ "$round" -lt 12 ]; do
|
||||||
|
round=$((round + 1))
|
||||||
|
changed=0
|
||||||
|
while IFS= read -r file; do
|
||||||
|
[ -f "$file" ] || continue
|
||||||
|
while IFS= read -r dep; do
|
||||||
|
case "$dep" in
|
||||||
|
/opt/homebrew/*|/usr/local/*)
|
||||||
|
base=$(basename "$dep")
|
||||||
|
if [ ! -f "$frameworks/$base" ]; then
|
||||||
|
cp "$dep" "$frameworks/$base"
|
||||||
|
chmod 755 "$frameworks/$base"
|
||||||
|
install_name_tool -id "@executable_path/../Frameworks/$base" "$frameworks/$base" >/dev/null 2>&1 || true
|
||||||
|
changed=1
|
||||||
|
fi
|
||||||
|
install_name_tool -change "$dep" "@executable_path/../Frameworks/$base" "$file" >/dev/null 2>&1 || true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done < <(otool -L "$file" | tail -n +2 | awk '{print $1}')
|
||||||
|
done < <(find "$app" -type f \( -perm -111 -o -name '*.dylib' \) -print)
|
||||||
|
|
||||||
|
[ "$changed" -eq 1 ] || break
|
||||||
|
done
|
||||||
|
|
||||||
|
left=$(find "$app" -type f \( -perm -111 -o -name '*.dylib' \) -exec otool -L {} + 2>/dev/null | grep -E '^[[:space:]]*(/opt/homebrew|/usr/local)/' | wc -l | tr -d ' ')
|
||||||
|
if [ "$left" -ne 0 ]; then
|
||||||
|
echo "还有 $left 个 Homebrew 依赖没处理:" >&2
|
||||||
|
find "$app" -type f \( -perm -111 -o -name '*.dylib' \) -exec otool -L {} + 2>/dev/null | grep -E '^[[:space:]]*(/opt/homebrew|/usr/local)/' | head -20 >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
; VoiletMark Windows 安装包(未签名)
|
||||||
|
; 按当前用户安装(不需要管理员权限),默认装到 %LOCALAPPDATA%\Programs\VoiletMark
|
||||||
|
Unicode true
|
||||||
|
!include "MUI2.nsh"
|
||||||
|
!include "LogicLib.nsh"
|
||||||
|
|
||||||
|
!ifndef APP_VERSION
|
||||||
|
!define APP_VERSION "0.0.0"
|
||||||
|
!endif
|
||||||
|
!ifndef DEPLOY_DIR
|
||||||
|
!error "需要 /DDEPLOY_DIR=<windeployqt 输出目录>"
|
||||||
|
!endif
|
||||||
|
!ifndef ICON_FILE
|
||||||
|
!define ICON_FILE "packaging\voiletmark.ico"
|
||||||
|
!endif
|
||||||
|
!ifndef OUTPUT_FILE
|
||||||
|
!define OUTPUT_FILE "dist\VoiletMark-setup.exe"
|
||||||
|
!endif
|
||||||
|
|
||||||
|
!define APP_NAME "VoiletMark"
|
||||||
|
!define APP_EXE "VoiletMark.exe"
|
||||||
|
!define APP_PUBLISHER "VoiletMark"
|
||||||
|
!define APP_ID "VoiletMark"
|
||||||
|
!define UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${APP_ID}"
|
||||||
|
|
||||||
|
Name "${APP_NAME} ${APP_VERSION}"
|
||||||
|
OutFile "${OUTPUT_FILE}"
|
||||||
|
InstallDir "$LOCALAPPDATA\Programs\${APP_NAME}"
|
||||||
|
InstallDirRegKey HKCU "Software\${APP_ID}" "InstallDir"
|
||||||
|
RequestExecutionLevel user
|
||||||
|
SetCompressor /SOLID lzma
|
||||||
|
CRCCheck on
|
||||||
|
BrandingText "${APP_NAME} ${APP_VERSION}"
|
||||||
|
|
||||||
|
!define MUI_ICON "${ICON_FILE}"
|
||||||
|
!define MUI_UNICON "${ICON_FILE}"
|
||||||
|
!define MUI_ABORTWARNING
|
||||||
|
!define MUI_WELCOMEPAGE_TITLE "${APP_NAME} ${APP_VERSION}"
|
||||||
|
!define MUI_WELCOMEPAGE_TEXT "把 ${APP_NAME} 装到当前用户目录,不需要管理员权限。$\r$\n$\r$\n安装后会把 .md 文件关联到 ${APP_NAME},随时可以在 Windows 设置里改回去。"
|
||||||
|
!define MUI_FINISHPAGE_RUN "$INSTDIR\${APP_EXE}"
|
||||||
|
!define MUI_FINISHPAGE_RUN_TEXT "立即运行 ${APP_NAME}"
|
||||||
|
|
||||||
|
!insertmacro MUI_PAGE_WELCOME
|
||||||
|
!insertmacro MUI_PAGE_DIRECTORY
|
||||||
|
!insertmacro MUI_PAGE_INSTFILES
|
||||||
|
!insertmacro MUI_PAGE_FINISH
|
||||||
|
!insertmacro MUI_UNPAGE_CONFIRM
|
||||||
|
!insertmacro MUI_UNPAGE_INSTFILES
|
||||||
|
|
||||||
|
!insertmacro MUI_LANGUAGE "SimpChinese"
|
||||||
|
!insertmacro MUI_LANGUAGE "English"
|
||||||
|
|
||||||
|
Section "VoiletMark" SecMain
|
||||||
|
SetShellVarContext current
|
||||||
|
SetOutPath "$INSTDIR"
|
||||||
|
File /r "${DEPLOY_DIR}\*.*"
|
||||||
|
WriteUninstaller "$INSTDIR\uninstall.exe"
|
||||||
|
|
||||||
|
; 开始菜单 + 桌面快捷方式
|
||||||
|
CreateDirectory "$SMPROGRAMS\${APP_NAME}"
|
||||||
|
CreateShortcut "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk" "$INSTDIR\${APP_EXE}"
|
||||||
|
CreateShortcut "$SMPROGRAMS\${APP_NAME}\卸载 ${APP_NAME}.lnk" "$INSTDIR\uninstall.exe"
|
||||||
|
CreateShortcut "$DESKTOP\${APP_NAME}.lnk" "$INSTDIR\${APP_EXE}"
|
||||||
|
|
||||||
|
; .md 关联(只写 HKCU,不动系统级关联)
|
||||||
|
WriteRegStr HKCU "Software\Classes\.md" "" "${APP_ID}.md"
|
||||||
|
WriteRegStr HKCU "Software\Classes\.md" "Content Type" "text/markdown"
|
||||||
|
WriteRegStr HKCU "Software\Classes\${APP_ID}.md" "" "Markdown 文档"
|
||||||
|
WriteRegStr HKCU "Software\Classes\${APP_ID}.md" "FriendlyTypeName" "Markdown 文档"
|
||||||
|
WriteRegStr HKCU "Software\Classes\${APP_ID}.md\DefaultIcon" "" "$INSTDIR\${APP_EXE},0"
|
||||||
|
WriteRegStr HKCU "Software\Classes\${APP_ID}.md\shell\open\command" "" '"$INSTDIR\${APP_EXE}" "%1"'
|
||||||
|
|
||||||
|
; 「打开方式」里也出现一份
|
||||||
|
WriteRegStr HKCU "Software\Classes\Applications\${APP_EXE}" "FriendlyAppName" "${APP_NAME}"
|
||||||
|
WriteRegStr HKCU "Software\Classes\Applications\${APP_EXE}\shell\open\command" "" '"$INSTDIR\${APP_EXE}" "%1"'
|
||||||
|
WriteRegStr HKCU "Software\Classes\Applications\${APP_EXE}\SupportedTypes" ".md" ""
|
||||||
|
|
||||||
|
; 让资源管理器立刻刷新图标 / 关联
|
||||||
|
System::Call 'shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
|
||||||
|
|
||||||
|
; 控制面板「卸载程序」
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "DisplayName" "${APP_NAME}"
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "DisplayVersion" "${APP_VERSION}"
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "Publisher" "${APP_PUBLISHER}"
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "DisplayIcon" "$INSTDIR\${APP_EXE}"
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "InstallLocation" "$INSTDIR"
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "UninstallString" '"$INSTDIR\uninstall.exe"'
|
||||||
|
WriteRegStr HKCU "${UNINST_KEY}" "QuietUninstallString" '"$INSTDIR\uninstall.exe" /S'
|
||||||
|
WriteRegDWORD HKCU "${UNINST_KEY}" "NoModify" 1
|
||||||
|
WriteRegDWORD HKCU "${UNINST_KEY}" "NoRepair" 1
|
||||||
|
WriteRegStr HKCU "Software\${APP_ID}" "InstallDir" "$INSTDIR"
|
||||||
|
SectionEnd
|
||||||
|
|
||||||
|
Section "Uninstall"
|
||||||
|
SetShellVarContext current
|
||||||
|
|
||||||
|
Delete "$DESKTOP\${APP_NAME}.lnk"
|
||||||
|
Delete "$SMPROGRAMS\${APP_NAME}\${APP_NAME}.lnk"
|
||||||
|
Delete "$SMPROGRAMS\${APP_NAME}\卸载 ${APP_NAME}.lnk"
|
||||||
|
RMDir "$SMPROGRAMS\${APP_NAME}"
|
||||||
|
|
||||||
|
; 只在 .md 仍指向我们时才清掉默认值,别破坏用户后来改的关联
|
||||||
|
ReadRegStr $0 HKCU "Software\Classes\.md" ""
|
||||||
|
${If} $0 == "${APP_ID}.md"
|
||||||
|
DeleteRegValue HKCU "Software\Classes\.md" ""
|
||||||
|
${EndIf}
|
||||||
|
DeleteRegKey HKCU "Software\Classes\${APP_ID}.md"
|
||||||
|
DeleteRegKey HKCU "Software\Classes\Applications\${APP_EXE}"
|
||||||
|
|
||||||
|
DeleteRegKey HKCU "${UNINST_KEY}"
|
||||||
|
DeleteRegKey HKCU "Software\${APP_ID}"
|
||||||
|
|
||||||
|
RMDir /r "$INSTDIR"
|
||||||
|
|
||||||
|
System::Call 'shell32::SHChangeNotify(i 0x8000000, i 0, i 0, i 0)'
|
||||||
|
SectionEnd
|
||||||
Reference in New Issue
Block a user