mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-08-08 07:33:35 +08:00
- 根据当前安装标记精确选择 MSI 或 Portable 更新包 - MSI 更新下载到用户缓存并通过 msiexec 保留原目录安装重启 - 下载与安装前校验包类型并隔离不同安装方式的缓存 - 补充安装模式、脚本执行和更新清理测试
109 lines
3.1 KiB
Go
109 lines
3.1 KiB
Go
package app
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
const windowsMSIInstallMarker = ".gonavi-msi-install"
|
|
|
|
type updateInstallMode string
|
|
|
|
const (
|
|
updateInstallModeUnknown updateInstallMode = "unknown"
|
|
updateInstallModePortable updateInstallMode = "portable"
|
|
updateInstallModeMSI updateInstallMode = "msi"
|
|
)
|
|
|
|
type updatePackageType string
|
|
|
|
const (
|
|
updatePackageTypePortable updatePackageType = "portable"
|
|
updatePackageTypeMSI updatePackageType = "msi"
|
|
updatePackageTypeDMG updatePackageType = "dmg"
|
|
updatePackageTypeArchive updatePackageType = "archive"
|
|
)
|
|
|
|
func resolveCurrentUpdateInstallMode() updateInstallMode {
|
|
return resolveUpdateInstallModeForExecutable(runtime.GOOS, updateResolveInstallTarget())
|
|
}
|
|
|
|
func resolveUpdateInstallModeForExecutable(goos string, executablePath string) updateInstallMode {
|
|
if !strings.EqualFold(strings.TrimSpace(goos), "windows") {
|
|
return updateInstallModeUnknown
|
|
}
|
|
executablePath = strings.TrimSpace(executablePath)
|
|
if executablePath == "" {
|
|
return updateInstallModeUnknown
|
|
}
|
|
markerPath := filepath.Join(filepath.Dir(executablePath), windowsMSIInstallMarker)
|
|
info, err := os.Stat(markerPath)
|
|
if err == nil {
|
|
if info.IsDir() {
|
|
return updateInstallModeUnknown
|
|
}
|
|
return updateInstallModeMSI
|
|
}
|
|
if errors.Is(err, os.ErrNotExist) {
|
|
return updateInstallModePortable
|
|
}
|
|
return updateInstallModeUnknown
|
|
}
|
|
|
|
func resolveUpdatePackageType(goos string, installMode updateInstallMode) updatePackageType {
|
|
switch strings.ToLower(strings.TrimSpace(goos)) {
|
|
case "windows":
|
|
if installMode == updateInstallModeMSI {
|
|
return updatePackageTypeMSI
|
|
}
|
|
if installMode == updateInstallModePortable {
|
|
return updatePackageTypePortable
|
|
}
|
|
case "darwin":
|
|
return updatePackageTypeDMG
|
|
case "linux":
|
|
return updatePackageTypeArchive
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func isUpdatePackageCompatibleWithInstallMode(goos string, installMode updateInstallMode, packageType updatePackageType, assetPath string) bool {
|
|
if !strings.EqualFold(strings.TrimSpace(goos), "windows") {
|
|
return true
|
|
}
|
|
extension := strings.ToLower(strings.TrimSpace(filepath.Ext(strings.TrimSpace(assetPath))))
|
|
switch installMode {
|
|
case updateInstallModeMSI:
|
|
return packageType == updatePackageTypeMSI && extension == ".msi"
|
|
case updateInstallModePortable:
|
|
return packageType == updatePackageTypePortable && extension == ".exe"
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func validateUpdatePackageForCurrentInstallMode(goos string, declaredMode updateInstallMode, packageType updatePackageType, assetPath string) error {
|
|
if !strings.EqualFold(strings.TrimSpace(goos), "windows") {
|
|
return nil
|
|
}
|
|
currentMode := updateResolveInstallMode()
|
|
if currentMode == updateInstallModeUnknown || declaredMode != currentMode ||
|
|
!isUpdatePackageCompatibleWithInstallMode(goos, currentMode, packageType, assetPath) {
|
|
return localizedUpdateError{
|
|
key: "app.update.backend.error.online_update_unsupported",
|
|
params: map[string]any{
|
|
"platform": strings.Join([]string{
|
|
strings.TrimSpace(goos),
|
|
string(currentMode),
|
|
string(declaredMode),
|
|
string(packageType),
|
|
}, "/"),
|
|
},
|
|
}
|
|
}
|
|
return nil
|
|
}
|