|
@@ -1,273 +0,0 @@
|
|
|
-package main
|
|
|
-
|
|
|
-import (
|
|
|
- "fmt"
|
|
|
- "image/color"
|
|
|
- "log"
|
|
|
- "os"
|
|
|
- "os/exec"
|
|
|
- "path/filepath"
|
|
|
- "time"
|
|
|
- "updater/download"
|
|
|
-
|
|
|
- "gioui.org/app"
|
|
|
- "gioui.org/io/system"
|
|
|
- "gioui.org/layout"
|
|
|
- "gioui.org/op"
|
|
|
- "gioui.org/text"
|
|
|
- "gioui.org/unit"
|
|
|
- "gioui.org/widget/material"
|
|
|
- "github.com/jessevdk/go-flags"
|
|
|
- "github.com/nats-io/nats.go"
|
|
|
- "infish.cn/comm"
|
|
|
-)
|
|
|
-
|
|
|
-// 启动程序
|
|
|
-// 下载文件->成功->失败
|
|
|
-// 下载成功->通知nats关闭原程序
|
|
|
-// 安装->成功->失败
|
|
|
-// 成功启动程序
|
|
|
-// 失败还原程序,关闭更新应用
|
|
|
-
|
|
|
-// Define the progress variables, a channel and a variable
|
|
|
-
|
|
|
-var progress float32
|
|
|
-var progressIncrementer chan float32
|
|
|
-
|
|
|
-var GAppOption = &AppOption{}
|
|
|
-
|
|
|
-type AppOption struct {
|
|
|
- NatsPort int `short:"p" long:"np" description:"nats port"`
|
|
|
- Url string `short:"u" long:"url" description:"url"`
|
|
|
-}
|
|
|
-
|
|
|
-func (o *AppOption) Parse() {
|
|
|
- flags.NewParser(o, flags.Default|flags.IgnoreUnknown).Parse()
|
|
|
-}
|
|
|
-
|
|
|
-type ProcesCallback = func(int, string)
|
|
|
-
|
|
|
-func upgradeLancherExe(url string, cb ProcesCallback) {
|
|
|
- exepath, _ := os.Executable()
|
|
|
- appExeDir, _ := filepath.Split(exepath)
|
|
|
-
|
|
|
- //1 下载lancher.exe
|
|
|
- downLancherExe := filepath.Join(appExeDir, "lancher")
|
|
|
- err := download.DownloadExe(GAppOption.Url, downLancherExe)
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- cb(-1, "下载安装包失败!")
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- //2 通知lancher.exe退出
|
|
|
- remoteCnn, err := comm.NewNatsBus(fmt.Sprintf("nats://localhost:%d", GAppOption.NatsPort), 1, 1, []*comm.NatsStreamWather{})
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- cb(-1, "安装失败!")
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- err = remoteCnn.Publish("lancher.quit", []byte{})
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- cb(-1, "安装失败!")
|
|
|
- return
|
|
|
- }
|
|
|
- remoteCnn.GetNatsConn().Flush()
|
|
|
-
|
|
|
- time.Sleep(time.Second * 2)
|
|
|
-
|
|
|
- //3 安装新的lancher.exe
|
|
|
- currLancherExe := filepath.Join(appExeDir, "lancher.exe")
|
|
|
- currLancherExeback := filepath.Join(appExeDir, "lancher.exe.back")
|
|
|
- err = os.Rename(currLancherExe, currLancherExeback)
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- cb(-1, "安装失败!")
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- err = os.Rename(downLancherExe, currLancherExe)
|
|
|
-
|
|
|
- if err != nil {
|
|
|
- fmt.Println(err)
|
|
|
- cb(-1, "安装失败!")
|
|
|
- os.Rename(currLancherExeback, currLancherExe)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- //4 启动lancher.exe
|
|
|
- // 重启
|
|
|
- cmd := exec.Command(currLancherExe)
|
|
|
- cmd.Stdout = os.Stdout
|
|
|
- cmd.Stderr = os.Stderr
|
|
|
- err = cmd.Start()
|
|
|
- if err != nil {
|
|
|
- fmt.Printf("failed to call cmd.Start(): %v", err)
|
|
|
- os.Rename(currLancherExeback, currLancherExe)
|
|
|
- cb(-1, "新包启动失败!")
|
|
|
- return
|
|
|
- }
|
|
|
- cb(1, "")
|
|
|
-}
|
|
|
-
|
|
|
-var installError = ""
|
|
|
-var installSucc = false
|
|
|
-
|
|
|
-func main() {
|
|
|
- GAppOption.Parse()
|
|
|
-
|
|
|
- fmt.Println("firt main xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
|
|
|
-
|
|
|
- //2 通知lancher.exe退出
|
|
|
- remoteCnn, _ := comm.NewNatsBus(fmt.Sprintf("nats://localhost:%d", GAppOption.NatsPort), 1, 1, []*comm.NatsStreamWather{})
|
|
|
-
|
|
|
- remoteCnn.AddReplyers(&comm.NatsMsgReplyer{
|
|
|
- Subject: "lancher.quit",
|
|
|
- Cb: func(msg *nats.Msg, entity interface{}) interface{} {
|
|
|
- go func() {
|
|
|
- time.Sleep(time.Second)
|
|
|
- os.Exit(0)
|
|
|
- }()
|
|
|
- return nil
|
|
|
- },
|
|
|
- })
|
|
|
-
|
|
|
- go func() {
|
|
|
- remoteCnn.Run(func() {})
|
|
|
- }()
|
|
|
-
|
|
|
- // // Setup a separate channel to provide ticks to increment progress
|
|
|
- progressIncrementer = make(chan float32)
|
|
|
- go func() {
|
|
|
- for {
|
|
|
- time.Sleep(time.Second / 25)
|
|
|
- progressIncrementer <- 0.004
|
|
|
- }
|
|
|
- }()
|
|
|
-
|
|
|
- w := app.NewWindow(
|
|
|
- app.Title("uploader"),
|
|
|
- app.Size(unit.Dp(600), unit.Dp(400)),
|
|
|
- )
|
|
|
-
|
|
|
- go func() {
|
|
|
- // create new window
|
|
|
-
|
|
|
- if err := draw(w); err != nil {
|
|
|
- log.Fatal(err)
|
|
|
- }
|
|
|
- os.Exit(0)
|
|
|
- }()
|
|
|
-
|
|
|
- go func() {
|
|
|
- time.Sleep(3 * time.Second)
|
|
|
-
|
|
|
- cmd := exec.Command("./updater", "--np=14220", "--url=https://lancher.obs.cn-east-3.myhuaweicloud.com/test/main")
|
|
|
- cmd.Stdout = os.Stdout
|
|
|
- cmd.Stderr = os.Stderr
|
|
|
-
|
|
|
- fmt.Println("started = >", cmd.Start())
|
|
|
- }()
|
|
|
-
|
|
|
- app.Main()
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-type C = layout.Context
|
|
|
-type D = layout.Dimensions
|
|
|
-
|
|
|
-func draw(w *app.Window) error {
|
|
|
- // ops are the operations from the UI
|
|
|
- var ops op.Ops
|
|
|
-
|
|
|
- // startButton is a clickable widget
|
|
|
- // var startButton widget.Clickable
|
|
|
-
|
|
|
- // is the egg boiling?
|
|
|
- var boiling bool
|
|
|
-
|
|
|
- // th defines the material design style
|
|
|
- th := material.NewTheme()
|
|
|
-
|
|
|
- for {
|
|
|
- select {
|
|
|
- // listen for events in the window.
|
|
|
- case e := <-w.Events():
|
|
|
-
|
|
|
- // detect what type of event
|
|
|
- switch e := e.(type) {
|
|
|
-
|
|
|
- // this is sent when the application should re-render.
|
|
|
- case system.FrameEvent:
|
|
|
-
|
|
|
- gtx := layout.NewContext(&ops, e)
|
|
|
-
|
|
|
- title := material.H1(th, "下载中")
|
|
|
- maroon := color.NRGBA{R: 127, G: 0, B: 0, A: 255}
|
|
|
- title.Color = maroon
|
|
|
- title.Alignment = text.Middle
|
|
|
- title.Layout(gtx)
|
|
|
- e.Frame(gtx.Ops)
|
|
|
-
|
|
|
- // gtx := layout.NewContext(&ops, e)
|
|
|
- // // Let's try out the flexbox layout concept
|
|
|
- // if startButton.Clicked() {
|
|
|
- // boiling = !boiling
|
|
|
- // }
|
|
|
-
|
|
|
- // layout.Flex{
|
|
|
- // // Vertical alignment, from top to bottom
|
|
|
- // Axis: layout.Vertical,
|
|
|
- // // Empty space is left at the start, i.e. at the top
|
|
|
- // Spacing: layout.SpaceStart,
|
|
|
- // }.Layout(gtx,
|
|
|
- // // layout.Rigid(
|
|
|
- // // func(gtx C) D {
|
|
|
- // // bar := material.ProgressBar(th, progress)
|
|
|
- // // return bar.Layout(gtx)
|
|
|
- // // },
|
|
|
- // // ),
|
|
|
- // layout.Rigid(
|
|
|
- // func(gtx C) D {
|
|
|
- // // We start by defining a set of margins
|
|
|
- // margins := layout.Inset{
|
|
|
- // Top: unit.Dp(25),
|
|
|
- // Bottom: unit.Dp(25),
|
|
|
- // Right: unit.Dp(25),
|
|
|
- // Left: unit.Dp(25),
|
|
|
- // }
|
|
|
- // // Then we lay out within those margins ...
|
|
|
- // return margins.Layout(gtx,
|
|
|
- // // ...the same function we earlier used to create a button
|
|
|
- // func(gtx C) D {
|
|
|
- // var text string
|
|
|
- // if !boiling {
|
|
|
- // text = "Start"
|
|
|
- // } else {
|
|
|
- // text = "Stop"
|
|
|
- // }
|
|
|
- // btn := material.Button(th, &startButton, text)
|
|
|
- // return btn.Layout(gtx)
|
|
|
- // },
|
|
|
- // )
|
|
|
- // },
|
|
|
- // ),
|
|
|
- // )
|
|
|
- // e.Frame(gtx.Ops)
|
|
|
-
|
|
|
- // this is sent when the application is closed.
|
|
|
- case system.DestroyEvent:
|
|
|
- return e.Err
|
|
|
- }
|
|
|
-
|
|
|
- //listen for events in the incrementor channel
|
|
|
- case p := <-progressIncrementer:
|
|
|
- if boiling && progress < 1 {
|
|
|
- progress += p
|
|
|
- w.Invalidate()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|