diff --git a/FyneApp.toml b/FyneApp.toml index 987a3c6..a6e45c5 100644 --- a/FyneApp.toml +++ b/FyneApp.toml @@ -4,5 +4,5 @@ Website = "https://chrome.noki.eu.org" Icon = "assets/img/chrome.png" Name = "chrome_updater" ID = "com.github.libs.chrome" - Version = "1.8" + Version = "1.9" Build = 0 diff --git a/base.go b/base.go index f236cb5..39c047f 100644 --- a/base.go +++ b/base.go @@ -135,6 +135,9 @@ func baseScreen(win fyne.Window, data *SettingsData) fyne.CanvasObject { bar := container.NewBorder(nil, nil, buttons, nil, folderEntry) curVerLabel := widget.NewLabelWithData(data.curVer) curVerLabel.TextStyle.Bold = true + oldVer := GetVersion(data, "chrome.exe") + logger.Info("chrome version:", oldVer) + _ = data.oldVer.Set(oldVer) form := widget.NewForm( &widget.FormItem{Text: LoadString("InstallLabel"), Widget: bar}, &widget.FormItem{Text: LoadString("BranchLabel"), Widget: versionRadio}, diff --git a/chrome_auto_update.go b/chrome_auto_update.go index 102c1a2..1a7aba4 100644 --- a/chrome_auto_update.go +++ b/chrome_auto_update.go @@ -70,6 +70,9 @@ func addUpdateCron(data *SettingsData) { _ = data.SHA1.Set(chromeInfo.Sha1) _ = data.SHA256.Set(chromeInfo.Sha256) _ = data.downBtnStatus.Set(false) + oldVer := GetVersion(data, "chrome.exe") + logger.Info("chrome version:", oldVer) + _ = data.oldVer.Set(oldVer) ov, _ := data.oldVer.Get() cv, _ := data.curVer.Get() if cv != ov { diff --git a/chrome_plus.go b/chrome_plus.go index 4d1cbdd..0ff7072 100644 --- a/chrome_plus.go +++ b/chrome_plus.go @@ -73,6 +73,9 @@ func chromePlusScreen(win fyne.Window, data *SettingsData) fyne.CanvasObject { })) curVerLabel := widget.NewLabelWithData(data.curPlusVer) curVerLabel.TextStyle.Bold = true + oldPlusVer := GetVersion(data, "version.dll") + logger.Info("chrome++ version:", oldPlusVer) + _ = data.oldPlusVer.Set(oldPlusVer) form := widget.NewForm( &widget.FormItem{Text: LoadString("NowVerLabel"), Widget: widget.NewLabelWithData(data.oldPlusVer)}, &widget.FormItem{Text: LoadString("LatestVerLabel"), Widget: versionSelect}, diff --git a/common.go b/common.go index ff726a2..dfd377e 100644 --- a/common.go +++ b/common.go @@ -20,6 +20,14 @@ import ( "strconv" "strings" "syscall" + "unsafe" +) + +var ( + versionDLL = syscall.NewLazyDLL("version.dll") + procGetFileVersionInfo = versionDLL.NewProc("GetFileVersionInfoW") + procGetFileVersionInfoSize = versionDLL.NewProc("GetFileVersionInfoSizeW") + procVerQueryValue = versionDLL.NewProc("VerQueryValueW") ) // url转换 @@ -392,3 +400,78 @@ func handlerErr(err error, message string, win fyne.Window) { alertInfo(message, win) } } + +func GetFileVersion(path string) (string, error) { + p, err := syscall.UTF16PtrFromString(path) + if err != nil { + return "", err + } + + // Get the size of the version info + size, _, _ := procGetFileVersionInfoSize.Call(uintptr(unsafe.Pointer(p)), 0) + if size == 0 { + return "", fmt.Errorf("failed to get version info size") + } + + // Allocate a buffer to hold the version info + buffer := make([]byte, size) + + // Get the version info + ret, _, err := procGetFileVersionInfo.Call( + uintptr(unsafe.Pointer(p)), + 0, + uintptr(size), + uintptr(unsafe.Pointer(&buffer[0])), + ) + if ret == 0 { + return "", fmt.Errorf("failed to get version info: %v", err) + } + + // Query the VarFileInfo to find the language and code page + var block unsafe.Pointer + var blockLen uint32 + ret, _, err = procVerQueryValue.Call( + uintptr(unsafe.Pointer(&buffer[0])), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr("\\VarFileInfo\\Translation"))), + uintptr(unsafe.Pointer(&block)), + uintptr(unsafe.Pointer(&blockLen)), + ) + if ret == 0 { + return "", fmt.Errorf("failed to query translation value: %v", err) + } + + translations := (*[1 << 20][2]uint16)(block)[:blockLen/4] + if len(translations) == 0 { + return "", fmt.Errorf("no translations found") + } + + // Use the first translation found + langCodePage := fmt.Sprintf("%04x%04x", translations[0][0], translations[0][1]) + subBlock := fmt.Sprintf("\\StringFileInfo\\%s\\FileVersion", langCodePage) + + // Query the version value + ret, _, err = procVerQueryValue.Call( + uintptr(unsafe.Pointer(&buffer[0])), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subBlock))), + uintptr(unsafe.Pointer(&block)), + uintptr(unsafe.Pointer(&blockLen)), + ) + if ret == 0 { + return "", fmt.Errorf("failed to query version value: %v", err) + } + + version := syscall.UTF16ToString((*[1 << 20]uint16)(block)[:blockLen]) + return version, nil +} +func GetVersion(sd *SettingsData, fileName string) string { + exePath := filepath.Join(getString(sd.installPath), fileName) + if fileExist(exePath) { + ver, err := GetFileVersion(exePath) + if err == nil { + return ver + } else { + logger.Errorln(ver) + } + } + return "-" +}