在日常工作中,软件需要实现更新!在linux环境下,只需要检查版本号,拿到最新下载地址,下载解压替换掉执行文件然后重启即可。
但是在windows下,在程序未停止前是无法实现可执行文件替换的,所以在windows环境下,以多提供一个upgrade.exe的更新程序来实现。
具体实现方案:
1.检查版本,下载更新包;
2.执行upgrade.exe,并退出程序,解除程序暂用
3.upgrade程序实现更新包的解压,替换主程序
4.upgrade执行程序包.
这样就达到了程序的更新操作.
具体代码实现:
1.检查版本,并下载
func (s *ServerImpl) winUpgrade(e echo.Context) error { spVersion, err := servers.NewReportService().CheckVersion(1, 0) if err != nil { return errors.New("网络错误") } // 比较版本 if utils.CompareVersion(spVersion.Code, config.Version) != 1 { return e.JSON(http.StatusOK, "已经是最新版") } fmt.Println("Download Started") if spVersion.Down == "" { return errors.New("网络错误") } resp, err := http.Get(spVersion.Down) if err != nil { return errors.New("更新失败") } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return errors.New("更新失败") } // 保存文件 zipReader, err := zip.NewReader(bytes.NewReader(body), int64(len(body))) if err != nil { return errors.New("更新失败") } // 解压 if err = utils.DeCompress(zipReader.File, "./new_version"); err != nil { return errors.New("更新失败") } fmt.Println("Download Finished") go func() { // 唤起upgrade.exe start是非阻塞 /B是隐藏窗口 cmd := exec.Command("cmd.exe", "/C", "start", "/B", "upgrade.exe") if err = cmd.Start(); err != nil { fmt.Println(err) } fmt.Println("exit") os.Exit(0) }() return e.JSON(http.StatusOK, "更新成功") }
upgrade 程序替换并唤起主程序
// cmd的start执行不会等待命令完成,Run会阻塞等待命令完成
func main() {
fmt.Println("upgrade....")
fmt.Println("rename:")
os.Rename("cms.exe", fmt.Sprintf("%s-%s.exe", "cms", time.Now().Format("20060102150405")))
// 重命名cms.exe
os.Rename("./new_version/cms.exe", "./new_version/cms_new.exe")
gfile.CopyDir("./new_version/html", "./html")
if err := gfile.Copy("./new_version/cms_new.exe", "./cms.exe"); err != nil {
fmt.Println("copy err", err)
time.Sleep(10 * time.Second)
os.Exit(0)
}
gfile.Remove("./new_version")
//os.Rename("cms_new.exe", "cms.exe")
fmt.Println("starting.......")
cmd := exec.Command("cmd.exe", "/C", "start", "cms.exe")
if err := cmd.Start(); err != nil {
fmt.Println(err)
}
time.Sleep(5 * time.Second)
fmt.Println("upgrade exit")
os.Exit(0)
}
这样就达到了,程序更新的效果