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

喜欢逆向关注我,精通各种逆向工程,会编写各类爬虫。喜欢私聊。

Logo

瓜分20万奖金 获得内推名额 丰厚实物奖励 易参与易上手

更多推荐