go+git+windows脚本+windres打造软件升级程序,干货太多,[建议收藏]
go+git+windows脚本+windres打造软件升级程序,干货太多
1)go.mod如下:
module go_exe
go 1.19
2)准备一个logo.ico图片
3)准备upexe.mainfest如下:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> <requestedExecutionLevel level="requireAdministrator"/> </requestedPrivileges> </security> </trustInfo> </assembly>
4)准备upexe.rc内容如下:
#define RT_MANIFEST 24 #include "version.h" #include "version_template.h" #define MAKEVER_S(a,b,c,d) a,b,c,d #define MAKEVER(a,b,c,d,e) a.b.c.d.e #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) 1 VERSIONINFO PRODUCTVERSION MAKEVER_S(VER_MAJOR, VER_MINOR, VER_PATCH, VER_REVISION) FILEVERSION MAKEVER_S(VER_MAJOR, VER_MINOR, VER_PATCH, VER_REVISION) BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904B0" BEGIN VALUE "CompanyName", "AA.inc" VALUE "FileDescription", "软件介绍" VALUE "FileVersion", TOSTRING(MAKEVER(VER_MAJOR, VER_MINOR, VER_PATCH, VER_REVISION, VER_REVISION_HASH)) VALUE "InternalName", "软件" VALUE "LegalCopyright", "Copyright (C) 2023. AA.inc All Rights Reserved." VALUE "OriginalFilename", "upexe.exe" VALUE "ProductName", "软件" VALUE "ProductVersion", TOSTRING(MAKEVER(VER_MAJOR, VER_MINOR, VER_PATCH, VER_REVISION, VER_REVISION_HASH)) END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x0409, 0x04B0 END END 1 ICON "logo.ico" 1 RT_MANIFEST "upexe.manifest"
5)version.h如下:
#define VER_REVISION 11 #define VER_REVISION_HASH d3c4538
6)version_template.h如下
#pragma once #define VER_MAJOR 1 #define VER_MINOR 0 #define VER_PATCH 1
7)make_upexe.bat如下:
cd "%~dp0" if exist "version.h" del /q "version.h" if exist "upexe.syso" del /q "upexe.syso" if exist "upexe.exe" del /q "upexe.exe" for /f "delims=" %%i in ('git rev-list --count HEAD') do (set REVISION=%%i) for /f "delims=" %%i in ('git rev-parse --short HEAD') do (set REVISION_HASH=%%i) if "%REVISION%" == "" ( set REVISION=0 ) (echo #define VER_REVISION %REVISION% && echo #define VER_REVISION_HASH %REVISION_HASH%) > "version.h" windres.exe -i upexe.rc -o upexe.syso go build -o upexe.exe
8)升级主程序代码如下:
package main
import (
"archive/zip"
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path"
_ "path/filepath"
"strings"
)
func getFileMd5(path string) string {
// 文件全路径名
pFile, err := os.Open(path)
if err != nil {
return ""
}
defer pFile.Close()
md5h := md5.New()
io.Copy(md5h, pFile)
return hex.EncodeToString(md5h.Sum(nil))
}
func checkErr(err error) {
if err != nil {
fmt.Println(err)
panic(err)
}
}
func readFile(path string) map[string]interface{} {
filePtr, err := ioutil.ReadFile(path)
if err != nil {
fmt.Println("Open file failed [Err:%s]", err.Error())
return nil
}
var c map[string]interface{}
err = json.Unmarshal(bytes.TrimPrefix(filePtr, []byte("\xef\xbb\xbf")), &c)
checkErr(err)
//fmt.Println(c["appInfo"].(map[string]interface{})["version"])
//c["appInfo"].(map[string]interface{})["version"] = "1.0.2"
return c
}
func writeFile(path string, c map[string]interface{}) {
// 创建文件
filePtr, err := os.Create(path)
if err != nil {
fmt.Println("Create file failed", err.Error())
return
}
defer filePtr.Close()
data, err := json.MarshalIndent(c, "", " ")
filePtr.Write(data)
}
func DeCompress_zip(zipFile, dest_path string) error {
reader, err := zip.OpenReader(zipFile)
if err != nil {
return err
}
defer reader.Close()
DeCompress_to_dest := func(f *zip.File) error {
rc, err := f.Open()
if err != nil {
return err
}
defer rc.Close()
filename := path.Join(dest_path, f.Name)
//if err = os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
// return err
//}
w, err := os.Create(filename)
if err != nil {
return err
}
defer w.Close()
_, err = io.Copy(w, rc)
return err
}
for _, file := range reader.File {
fmt.Println("unzip ", file.Name)
if file.FileInfo().IsDir() {
err := os.MkdirAll(path.Join(dest_path, file.Name), 0755)
if err != nil {
fmt.Println(err)
return err
}
continue
}
err := DeCompress_to_dest(file)
if err != nil {
return err
}
}
return nil
}
func Get(url string) map[string]interface{} {
var c map[string]interface{}
client := &http.Client{}
req, err := http.NewRequest("GET", url, nil)
checkErr(err)
req.Header.Add("Content-Type", "application/json;charset=UTF-8")
resp, err := client.Do(req)
checkErr(err)
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
checkErr(err)
err = json.Unmarshal(bytes.TrimPrefix(body, []byte("\xef\xbb\xbf")), &c)
checkErr(err)
return c
}
type WriteCounter struct {
Total uint64
}
func (wc *WriteCounter) Write(p []byte) (int, error) {
n := len(p)
wc.Total += uint64(n)
wc.PrintProgress()
return n, nil
}
func (wc WriteCounter) PrintProgress() {
fmt.Printf("\r%s", strings.Repeat(" ", 35))
fmt.Printf("\r文件下载中... %d B complete", wc.Total)
}
func main() {
fmt.Println("鱼抖抖更新程序")
url := "https://项目网址/member/login/systemVersion"
apath, _ := os.Getwd()
home := os.Getenv("LOCALAPPDATA")
c := Get(url)
//"config.json"
txtJson := readFile(path.Join(apath, "config.json"))
currVersion := fmt.Sprintf("%s", c["data"].(map[string]interface{})["currVersion"])
zipMd5 := fmt.Sprintf("%s", c["data"].(map[string]interface{})["zipMd5"])
zipUrl := fmt.Sprintf("%s", c["data"].(map[string]interface{})["zipUrl"])
version := fmt.Sprintf("%s", txtJson["appInfo"].(map[string]interface{})["version"])
if currVersion != version {
txtJson["appInfo"].(map[string]interface{})["version"] = currVersion
filePath2 := path.Join(home, "update.zip")
DownloadFile(filePath2, zipUrl)
if getFileMd5(filePath2) == zipMd5 {
fmt.Println("文件解压中")
err := DeCompress_zip(filePath2, apath)
if err == nil {
writeFile(path.Join(apath, "config.json"), txtJson)
}
}
}
datapath := path.Join(apath, "dy_new_start.exe")
exec.Command(datapath).Start()
}
// DownloadFile will download a url to a local file. It's efficient because it will
// write as it downloads and not load the whole file into memory. We pass an io.TeeReader
// into Copy() to report progress on the download.
func DownloadFile(filepath string, url string) error {
// Create the file, but give it a tmp file extension, this means we won't overwrite a
// file until it's downloaded, but we'll remove the tmp extension once downloaded.
out, err := os.Create(filepath + ".tmp")
if err != nil {
return err
}
//defer out.Close() 看评论
// Get the data
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
counter := &WriteCounter{}
_, err = io.Copy(out, io.TeeReader(resp.Body, counter))
if err != nil {
return err
}
out.Close() // 看评论
err = os.Rename(filepath+".tmp", filepath)
if err != nil {
return err
}
return nil
}
执行过程
最后只要双击make_upexe.bat就可以生成升级upexe.exe
喜欢逆向关注我,精通各种逆向工程,会编写各类爬虫。喜欢私聊。
更多推荐
所有评论(0)