84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"sentinel/pkg/log"
|
|
"sentinel/pkg/utils"
|
|
|
|
"sentinel/pkg/device"
|
|
"sentinel/pkg/net"
|
|
)
|
|
|
|
func main() {
|
|
deviceID := device.GetDeviceID()
|
|
fmt.Printf("[updater] device id: %s\n", deviceID)
|
|
|
|
exeDir, _ := os.Executable()
|
|
target := filepath.Join(filepath.Dir(exeDir), "main_program_binary_name") // TODO: 替换
|
|
|
|
if err := RunUpdate(deviceID, target); err != nil {
|
|
log.Fatalf("[updater] update failed: %v", err)
|
|
}
|
|
fmt.Println("[updater] update finished")
|
|
}
|
|
|
|
// RunUpdate 检查更新、下载、替换主程序并启动新程序
|
|
func RunUpdate(deviceID string, targetExe string) error {
|
|
info, err := api.CheckUpdate(deviceID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
// 2. 比对本地版本
|
|
if info.Version <= utils.APP_VERSION {
|
|
fmt.Println("[updater] already latest version:", utils.APP_VERSION)
|
|
return nil
|
|
}
|
|
fmt.Println("[updater] updating to version:", info.Version, "notes:", info.Notes)
|
|
|
|
// 3. 下载新版本到临时目录
|
|
tmpFile := filepath.Join(os.TempDir(), "new_program_tmp")
|
|
out, err := os.Create(tmpFile)
|
|
if err != nil {
|
|
return fmt.Errorf("create temp file failed: %w", err)
|
|
}
|
|
defer out.Close()
|
|
|
|
resp2, err := http.Get(info.DownloadURL)
|
|
if err != nil {
|
|
return fmt.Errorf("download failed: %w", err)
|
|
}
|
|
defer resp2.Body.Close()
|
|
|
|
h := sha256.New()
|
|
mw := io.MultiWriter(out, h)
|
|
if _, err := io.Copy(mw, resp2.Body); err != nil {
|
|
return fmt.Errorf("write temp file failed: %w", err)
|
|
}
|
|
|
|
// 4. 替换 targetExe
|
|
backup := targetExe + ".bak"
|
|
_ = os.Remove(backup)
|
|
_ = os.Rename(targetExe, backup) // 备份旧版本
|
|
if err := os.Rename(tmpFile, targetExe); err != nil {
|
|
return fmt.Errorf("replace main program failed: %w", err)
|
|
}
|
|
fmt.Println("[updater] replaced main program")
|
|
|
|
// 5. 启动新主程序
|
|
cmd := exec.Command(targetExe)
|
|
cmd.Stdout = os.Stdout
|
|
cmd.Stderr = os.Stderr
|
|
if err := cmd.Start(); err != nil {
|
|
return fmt.Errorf("start new program failed: %w", err)
|
|
}
|
|
|
|
fmt.Println("[updater] new program started successfully")
|
|
return nil
|
|
}
|