1715 lines
53 KiB
Go
1715 lines
53 KiB
Go
package main
|
||
|
||
//import (
|
||
// "bufio"
|
||
// "context"
|
||
// "encoding/json"
|
||
// "fmt"
|
||
// "gopkg.in/yaml.v3"
|
||
// "io"
|
||
// "io/ioutil"
|
||
// "net"
|
||
// "net/http"
|
||
// "os"
|
||
// "os/exec"
|
||
// "path/filepath"
|
||
// "strings"
|
||
// "syscall"
|
||
// "time"
|
||
// "unsafe"
|
||
//)
|
||
//
|
||
//// 颜色代码常量
|
||
//const (
|
||
// ColorReset = "\033[0m"
|
||
// ColorRed = "\033[31m"
|
||
// ColorGreen = "\033[32m"
|
||
// ColorYellow = "\033[33m"
|
||
// ColorBlue = "\033[34m"
|
||
// ColorMagenta = "\033[35m"
|
||
// ColorCyan = "\033[36m"
|
||
// ColorWhite = "\033[37m"
|
||
// ColorGray = "\033[90m"
|
||
//
|
||
// // 加粗
|
||
// ColorBoldRed = "\033[1;31m"
|
||
// ColorBoldGreen = "\033[1;32m"
|
||
// ColorBoldYellow = "\033[1;33m"
|
||
// ColorBoldBlue = "\033[1;34m"
|
||
//
|
||
// // 背景色
|
||
// ColorBgRed = "\033[41m"
|
||
// ColorBgGreen = "\033[42m"
|
||
//)
|
||
//
|
||
//// 定义结构体来映射 YAML 数据
|
||
//type VersionConfig struct {
|
||
// CsvVersion string `json:"csv"`
|
||
// KongfzVersion string `json:"kongfz"`
|
||
// LoggerVersion string `json:"logger"`
|
||
// ModuleErpVersion string `json:"module-erp"`
|
||
// ModuleKongfzVersion string `json:"module-kongfz"`
|
||
// ModuleTaskPoolVersion string `json:"module-taskPool"`
|
||
// ModuleVerifyPriceVersion string `json:"module-verifyPrice"`
|
||
// ModuleCenterBookVersion string `json:"module-centerBook"`
|
||
// ModuleLoginVersion string `json:"module-login"`
|
||
// PicToolVersion string `json:"picTool"`
|
||
// ProxyVersion string `json:"proxy"`
|
||
//}
|
||
//
|
||
//type VerifyPriceYAML struct {
|
||
// VerifyPriceLatestVersion string `yaml:"verifyPriceLatestVersion"`
|
||
//}
|
||
//
|
||
//// 自定义日志函数,添加颜色
|
||
//func printInfo(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorCyan+"[信息] "+format+ColorReset+"\n", v...)
|
||
//}
|
||
//
|
||
//func printSuccess(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorGreen+"[成功] "+format+ColorReset+"\n", v...)
|
||
//}
|
||
//
|
||
//func printWarning(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorYellow+"[警告] "+format+ColorReset+"\n", v...)
|
||
//}
|
||
//
|
||
//func printError(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorRed+"[错误] "+format+ColorReset+"\n", v...)
|
||
//}
|
||
//
|
||
//func printDebug(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorGray+"[调试] "+format+ColorReset+"\n", v...)
|
||
//}
|
||
//
|
||
//func printBanner(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorBoldBlue+"== "+format+" ==\n"+ColorReset, v...)
|
||
//}
|
||
//
|
||
//func printDownload(format string, v ...interface{}) {
|
||
// fmt.Printf(ColorBoldGreen+"[下载] "+format+ColorReset+"\n", v...)
|
||
//}
|
||
//
|
||
//func printVersionInfo(label, version string) {
|
||
// fmt.Printf(ColorBoldYellow+"%-30s: "+ColorCyan+"%s"+ColorReset+"\n", label, version)
|
||
//}
|
||
//
|
||
//func main() {
|
||
// // 打印彩色横幅
|
||
// fmt.Printf(ColorBoldBlue + "================================================\n")
|
||
// fmt.Printf(" 核价软件更新器\n")
|
||
// fmt.Printf("================================================\n" + ColorReset)
|
||
// printWarning("更新时请勿操作!!!")
|
||
// // 获取当前工作目录
|
||
// currentDir, err := os.Getwd()
|
||
// if err != nil {
|
||
// printError("获取当前目录失败: %v", err)
|
||
// }
|
||
// printInfo("当前目录: %v", currentDir)
|
||
//
|
||
// // 获取选品中心中verify_price_version_test.json
|
||
// printInfo("正在检查核价软件版本...")
|
||
// verifyPriceVersionJSON, err := getVerifyPriceVersionJSON()
|
||
// if err != nil {
|
||
// printError("读取核价软件版本信息失败: %v", err)
|
||
// }
|
||
//
|
||
// // 直接读取yaml文件
|
||
// yamlPath := filepath.Join(currentDir, "version.yaml")
|
||
// // 读取 YAML 文件
|
||
// data, err := ioutil.ReadFile(yamlPath)
|
||
// if err != nil {
|
||
// printError("读取YAML配置文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 解析 YAML
|
||
// var config VerifyPriceYAML
|
||
// err = yaml.Unmarshal(data, &config)
|
||
// if err != nil {
|
||
// printError("解析 YAML 配置失败: %v", err)
|
||
// }
|
||
// printVersionInfo("当前核价软件版本号", config.VerifyPriceLatestVersion)
|
||
//
|
||
// // 检查并下载核价软件主程序
|
||
// printInfo("检查核价软件主程序...")
|
||
// if _, err := os.Stat(filepath.Join(currentDir, "VerifyPriceApp.exe")); os.IsNotExist(err) {
|
||
// printDownload("发现核价软件缺失,开始下载...")
|
||
// url := fmt.Sprintf("https://newverifyprice.buzhiyushu.cn/exe/VerifyPriceApp_%s.exe", verifyPriceVersionJSON.VerifyPriceLatestVersion)
|
||
// err = downloadEXE(url, currentDir, "VerifyPriceApp.exe")
|
||
// if err != nil {
|
||
// if err.Error() == "The process cannot access the file because it is being used by another process." {
|
||
// printWarning("文件被占用,请重新启动与书同行.exe软件")
|
||
// } else {
|
||
// printError("下载核价软件失败: %v", err)
|
||
// }
|
||
// } else {
|
||
// printSuccess("核价软件下载完成")
|
||
// }
|
||
// //修改yaml文件
|
||
// config.VerifyPriceLatestVersion = verifyPriceVersionJSON.VerifyPriceLatestVersion
|
||
// err = writeYAML(yamlPath, config)
|
||
// if err != nil {
|
||
// printError("更新YAML配置文件失败: %v", err)
|
||
// }
|
||
// } else {
|
||
// if verifyPriceVersionJSON.VerifyPriceLatestVersion != config.VerifyPriceLatestVersion || config.VerifyPriceLatestVersion == "" {
|
||
// printDownload("发现新版本核价软件,开始更新...")
|
||
// url := fmt.Sprintf("https://newverifyprice.buzhiyushu.cn/exe/VerifyPriceApp_%s.exe", verifyPriceVersionJSON.VerifyPriceLatestVersion)
|
||
// err = downloadEXE(url, currentDir, "VerifyPriceApp.exe")
|
||
// if err != nil {
|
||
// if err.Error() == "The process cannot access the file because it is being used by another process." {
|
||
// printWarning("文件被占用,请重新启动与书同行.exe软件")
|
||
// } else {
|
||
// printError("下载核价软件失败: %v", err)
|
||
// }
|
||
// } else {
|
||
// printSuccess("核价软件更新完成")
|
||
// }
|
||
// //修改yaml文件
|
||
// config.VerifyPriceLatestVersion = verifyPriceVersionJSON.VerifyPriceLatestVersion
|
||
// err = writeYAML(yamlPath, config)
|
||
// if err != nil {
|
||
// printError("更新YAML配置文件失败: %v", err)
|
||
// }
|
||
// } else {
|
||
// printSuccess("核价软件已是最新版本")
|
||
// }
|
||
// }
|
||
//
|
||
// // 获取ES2中version.json
|
||
// printInfo("正在检查DLL组件版本...")
|
||
// versionsJSON, err := getVersionsJSON()
|
||
// if err != nil {
|
||
// printError("读取DLL版本信息失败: %v", err)
|
||
// }
|
||
//
|
||
// // 打印版本信息标题
|
||
// printBanner("版本信息")
|
||
//
|
||
// // 打印所有版本信息
|
||
// printVersionInfo("最新核价软件版本", verifyPriceVersionJSON.VerifyPriceLatestVersion)
|
||
// printVersionInfo("csv.dll版本号:", versionsJSON.CsvVersion)
|
||
// printVersionInfo("kongfz.dll版本号:", versionsJSON.KongfzVersion)
|
||
// printVersionInfo("logger.dll版本号:", versionsJSON.LoggerVersion)
|
||
// printVersionInfo("module-centerBook.dll版本号:", versionsJSON.ModuleCenterBookVersion)
|
||
// printVersionInfo("module-login.dll版本号:", versionsJSON.ModuleLoginVersion)
|
||
// printVersionInfo("module-erp.dll版本号:", versionsJSON.ModuleErpVersion)
|
||
// printVersionInfo("module-kongfz.dll版本号:", versionsJSON.ModuleKongfzVersion)
|
||
// printVersionInfo("module-taskPool.dll版本号:", versionsJSON.ModuleTaskPoolVersion)
|
||
// printVersionInfo("module-verifyPrice.dll版本号:", versionsJSON.ModuleVerifyPriceVersion)
|
||
// printVersionInfo("picTool.dll版本号:", versionsJSON.PicToolVersion)
|
||
// printVersionInfo("proxy.dll版本号:", versionsJSON.ProxyVersion)
|
||
//
|
||
// // 验证并更新DLL文件
|
||
// printBanner("组件检查与更新")
|
||
//
|
||
// // 验证csv.dll文件版本
|
||
// printInfo("检查csv.dll...")
|
||
// csvVersion, err := csvDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取csv.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.CsvVersion != csvVersion && csvVersion != "" {
|
||
// printDownload("csv.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "csv.dll"), "csv.dll", "")
|
||
// if err != nil {
|
||
// printError("下载csv.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("csv.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("csv.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证kongfz.dll文件版本
|
||
// printInfo("检查kongfz.dll...")
|
||
// kongfzVersion, err := kongfzDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取kongfz.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.KongfzVersion != kongfzVersion && kongfzVersion != "" {
|
||
// printDownload("kongfz.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "kongfz.dll"), "kongfz.dll", "")
|
||
// if err != nil {
|
||
// printError("下载kongfz.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("kongfz.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("kongfz.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证logger.dll文件版本
|
||
// printInfo("检查logger.dll...")
|
||
// loggerVersion, err := loggerDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取logger.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.LoggerVersion != loggerVersion && loggerVersion != "" {
|
||
// printDownload("logger.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "logger.dll"), "logger.dll", "")
|
||
// if err != nil {
|
||
// printError("下载logger.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("logger.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("logger.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证module-centerBook.dll文件版本
|
||
// printInfo("检查module-centerBook.dll...")
|
||
// moduleCenterBookVersion, err := moduleCenterBookDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取module-centerBook.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ModuleCenterBookVersion != moduleCenterBookVersion && moduleCenterBookVersion != "" {
|
||
// printDownload("module-centerBook.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-centerBook.dll"), "module-centerBook.dll", "")
|
||
// if err != nil {
|
||
// printError("下载module-centerBook.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("module-centerBook.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("module-centerBook.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证module-login.dll文件版本
|
||
// printInfo("检查module-login.dll...")
|
||
// moduleLoginVersion, err := moduleLoginDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取module-login.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ModuleLoginVersion != moduleLoginVersion && moduleLoginVersion != "" {
|
||
// printDownload("module-login.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-login.dll"), "module-login.dll", "")
|
||
// if err != nil {
|
||
// printError("下载module-login.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("module-login.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("module-login.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证module-erp.dll文件版本
|
||
// printInfo("检查module-erp.dll...")
|
||
// moduleErpVersion, err := moduleErpDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取module-erp.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ModuleErpVersion != moduleErpVersion && moduleErpVersion != "" {
|
||
// printDownload("module-erp.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-erp.dll"), "module-erp.dll", "")
|
||
// if err != nil {
|
||
// printError("下载module-erp.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("module-erp.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("module-erp.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证module-kongfz.dll文件版本
|
||
// printInfo("检查module-kongfz.dll...")
|
||
// moduleKongfzVersion, err := moduleKongfzDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取module-kongfz.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ModuleKongfzVersion != moduleKongfzVersion && moduleKongfzVersion != "" {
|
||
// printDownload("module-kongfz.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-kongfz.dll"), "module-kongfz.dll", "")
|
||
// if err != nil {
|
||
// printError("下载module-kongfz.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("module-kongfz.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("module-kongfz.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证module-taskPool.dll文件版本
|
||
// printInfo("检查module-taskPool.dll...")
|
||
// moduleTaskPoolVersion, err := moduleTaskPoolDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取module-taskPool.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ModuleTaskPoolVersion != moduleTaskPoolVersion && moduleTaskPoolVersion != "" {
|
||
// printDownload("module-taskPool.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-taskPool.dll"), "module-taskPool.dll", "")
|
||
// if err != nil {
|
||
// printError("下载module-taskPool.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("module-taskPool.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("module-taskPool.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证module-verifyPrice.dll文件版本
|
||
// printInfo("检查module-verifyPrice.dll...")
|
||
// moduleVerifyPriceVersion, err := moduleVerifyPriceDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取module-verifyPrice.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ModuleVerifyPriceVersion != moduleVerifyPriceVersion && moduleVerifyPriceVersion != "" {
|
||
// printDownload("module-verifyPrice.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "module-verifyPrice.dll"), "module-verifyPrice.dll", "")
|
||
// if err != nil {
|
||
// printError("下载module-verifyPrice.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("module-verifyPrice.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("module-verifyPrice.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证picTool.dll文件版本
|
||
// printInfo("检查picTool.dll...")
|
||
// picToolVersion, err := picToolDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取picTool.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.PicToolVersion != picToolVersion && picToolVersion != "" {
|
||
// printDownload("picTool.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "picTool.dll"), "picTool.dll", "")
|
||
// if err != nil {
|
||
// printError("下载picTool.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("picTool.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("picTool.dll已是最新版本")
|
||
// }
|
||
//
|
||
// // 验证proxy.dll文件版本
|
||
// printInfo("检查proxy.dll...")
|
||
// proxyVersion, err := proxyDllVersion(currentDir)
|
||
// if err != nil {
|
||
// printWarning("获取proxy.dll版本失败: %v", err)
|
||
// }
|
||
// if versionsJSON.ProxyVersion != proxyVersion && proxyVersion != "" {
|
||
// printDownload("proxy.dll需要更新")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", filepath.Join(currentDir, "dll", "proxy.dll"), "proxy.dll", "")
|
||
// if err != nil {
|
||
// printError("下载proxy.dll失败: %v", err)
|
||
// } else {
|
||
// printSuccess("proxy.dll更新完成")
|
||
// }
|
||
// } else {
|
||
// printSuccess("proxy.dll已是最新版本")
|
||
// }
|
||
//
|
||
// printWarning("更新时请勿操作!!!出现:立即按回车键打开核价软件,可以点击 回车键")
|
||
//
|
||
// // 启动提示
|
||
// printBanner("启动核价软件")
|
||
// fmt.Printf("\n" + ColorBoldGreen + "立即按回车键打开核价软件..." + ColorReset)
|
||
// fmt.Printf(ColorGray + "(或30秒后自动打开)\n" + ColorReset)
|
||
//
|
||
// // 创建带超时的输入读取器
|
||
// inputCh := make(chan bool, 1)
|
||
//
|
||
// // 启动一个goroutine等待用户输入
|
||
// go func() {
|
||
// bufio.NewReader(os.Stdin).ReadBytes('\n')
|
||
// inputCh <- true
|
||
// }()
|
||
// // 设置30秒超时
|
||
// timeout := 30 * time.Second
|
||
//
|
||
// select {
|
||
// case <-inputCh:
|
||
// printSuccess("用户按下了回车键,立即打开核价软件")
|
||
// case <-time.After(timeout):
|
||
// printWarning("等待超时(30秒),自动打开核价软件")
|
||
// }
|
||
//
|
||
// // 尝试打开 VerifyPriceApp.exe
|
||
// verifyPriceAppPath := filepath.Join(currentDir, "VerifyPriceApp.exe")
|
||
// printInfo("正在启动核价软件: %s", verifyPriceAppPath)
|
||
//
|
||
// // 检查文件是否存在 --- TODO 存在问题,有可能打不开 VerifyPriceApp.exe
|
||
// if _, err := os.Stat(verifyPriceAppPath); os.IsNotExist(err) {
|
||
// printError("核价软件主程序不存在: %s", verifyPriceAppPath)
|
||
// } else {
|
||
// // 启动 VerifyPriceApp.exe
|
||
// cmd := exec.Command(verifyPriceAppPath)
|
||
//
|
||
// // 设置工作目录为当前目录
|
||
// cmd.Dir = currentDir
|
||
//
|
||
// // 启动进程(不等待它完成)
|
||
// err := cmd.Start()
|
||
// if err != nil {
|
||
// printError("启动核价软件失败: %v", err)
|
||
// } else {
|
||
// printSuccess("核价软件已启动 (PID: %d)", cmd.Process.Pid)
|
||
//
|
||
// // 给新进程一点时间启动(可选)
|
||
// time.Sleep(100 * time.Millisecond)
|
||
// }
|
||
// }
|
||
//
|
||
// printBanner("程序执行完毕")
|
||
//}
|
||
//
|
||
//// 将结构体写回YAML文件
|
||
//func writeYAML(filePath string, config VerifyPriceYAML) error {
|
||
// // 将结构体序列化为YAML
|
||
// yamlData, err := yaml.Marshal(config)
|
||
// if err != nil {
|
||
// return fmt.Errorf("序列化YAML失败: %v", err)
|
||
// }
|
||
//
|
||
// // 创建备份文件(可选)
|
||
// backupFilePath := filePath + ".bak"
|
||
// err = backupFile(filePath, backupFilePath)
|
||
// if err != nil {
|
||
// printDebug("创建备份文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 写回文件
|
||
// err = ioutil.WriteFile(filePath, yamlData, 0755)
|
||
// if err != nil {
|
||
// return fmt.Errorf("写入文件失败: %v", err)
|
||
// }
|
||
//
|
||
// return nil
|
||
//}
|
||
//
|
||
//// 备份原文件
|
||
//func backupFile(originalPath, backupPath string) error {
|
||
// // 读取原文件
|
||
// data, err := ioutil.ReadFile(originalPath)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
//
|
||
// // 写入备份文件
|
||
// return ioutil.WriteFile(backupPath, data, 0755)
|
||
//}
|
||
//
|
||
//func downloadEXE(url, folderPath, filename string) error {
|
||
// // 确保文件夹存在
|
||
// if err := os.MkdirAll(folderPath, 0755); err != nil {
|
||
// return fmt.Errorf("创建文件夹失败: %v", err)
|
||
// }
|
||
//
|
||
// // 拼接完整文件路径
|
||
// filePath := filepath.Join(folderPath, filename)
|
||
//
|
||
// printDebug("下载到: %s", filePath)
|
||
//
|
||
// // 发送HTTP请求
|
||
// resp, err := http.Get(url)
|
||
// if err != nil {
|
||
// return fmt.Errorf("请求失败: %v", err)
|
||
// }
|
||
// defer resp.Body.Close()
|
||
//
|
||
// // 检查响应状态
|
||
// if resp.StatusCode != http.StatusOK {
|
||
// return fmt.Errorf("下载失败,状态码: %d", resp.StatusCode)
|
||
// }
|
||
//
|
||
// // 创建文件
|
||
// file, err := os.Create(filePath)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建文件失败: %v", err)
|
||
// }
|
||
// defer file.Close()
|
||
//
|
||
// // 下载文件
|
||
// _, err = io.Copy(file, resp.Body)
|
||
// if err != nil {
|
||
// return fmt.Errorf("写入文件失败: %v", err)
|
||
// }
|
||
//
|
||
// return nil
|
||
//}
|
||
//
|
||
//// VersionInfo 定义 JSON 结构体
|
||
//type VersionInfo struct {
|
||
// LatestVersion string `json:"latestVersion"`
|
||
// HistoricalVersions []string `json:"historicalVersions"`
|
||
// VerifyPriceLatestVersion string `json:"verifyPriceLatestVersion"`
|
||
//}
|
||
//
|
||
//// 读取选品中心中verify_price_version_test.json文件
|
||
//func getVerifyPriceVersionJSON() (*VersionInfo, error) {
|
||
// // 目标 URL
|
||
// url := "https://newverifyprice.buzhiyushu.cn/verify_price_version.json"
|
||
//
|
||
// // 创建 HTTP 客户端,设置超时时间
|
||
// client := &http.Client{
|
||
// Timeout: 30 * time.Second,
|
||
// }
|
||
//
|
||
// // 发送 GET 请求
|
||
// resp, err := client.Get(url)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("请求失败: %v", err)
|
||
// }
|
||
// defer resp.Body.Close()
|
||
//
|
||
// // 检查响应状态码
|
||
// if resp.StatusCode != http.StatusOK {
|
||
// return nil, fmt.Errorf("HTTP 请求失败,状态码: %d", resp.StatusCode)
|
||
// }
|
||
//
|
||
// // 读取响应体
|
||
// body, err := io.ReadAll(resp.Body)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("读取响应失败: %v", err)
|
||
// }
|
||
//
|
||
// // 解析 JSON 数据
|
||
// var versionInfo VersionInfo
|
||
// err = json.Unmarshal(body, &versionInfo)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("解析 JSON 失败: %v", err)
|
||
// }
|
||
// return &versionInfo, nil
|
||
//}
|
||
//
|
||
//// 读取ES2中versions.json文件
|
||
//func getVersionsJSON() (*VersionConfig, error) {
|
||
// // 目标 URL
|
||
// url := "http://36.212.20.113:53300/version.json"
|
||
//
|
||
// // 创建 HTTP 客户端,设置超时时间
|
||
// client := &http.Client{
|
||
// Timeout: 30 * time.Second,
|
||
// }
|
||
//
|
||
// // 发送 GET 请求
|
||
// resp, err := client.Get(url)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("请求失败: %v", err)
|
||
// }
|
||
// defer resp.Body.Close()
|
||
//
|
||
// // 检查响应状态码
|
||
// if resp.StatusCode != http.StatusOK {
|
||
// return nil, fmt.Errorf("HTTP 请求失败,状态码: %d", resp.StatusCode)
|
||
// }
|
||
//
|
||
// // 读取响应体
|
||
// body, err := io.ReadAll(resp.Body)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("读取响应失败: %v", err)
|
||
// }
|
||
//
|
||
// // 解析 JSON 数据
|
||
// var versionConfig VersionConfig
|
||
// err = json.Unmarshal(body, &versionConfig)
|
||
// if err != nil {
|
||
// return nil, fmt.Errorf("解析 JSON 失败: %v", err)
|
||
// }
|
||
// return &versionConfig, nil
|
||
//}
|
||
//
|
||
//// cStr 将 C 字符串指针转换为 Go 字符串
|
||
//func cStr(ptr uintptr) string {
|
||
// if ptr == 0 {
|
||
// return ""
|
||
// }
|
||
// var b []byte
|
||
// for {
|
||
// c := *(*byte)(unsafe.Pointer(ptr))
|
||
// if c == 0 {
|
||
// break
|
||
// }
|
||
// b = append(b, c)
|
||
// ptr++
|
||
// }
|
||
// return string(b)
|
||
//}
|
||
//
|
||
//// 查询csv.dll版本号
|
||
//func csvDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "csv.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("csv.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "csv.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 csv.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载csv.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找csv.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用csv.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询kongfz.dll版本号
|
||
//func kongfzDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "kongfz.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("kongfz.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "kongfz.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 kongfz.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载kongfz.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找kongfz.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用kongfz.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询logger.dll版本号
|
||
//func loggerDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "logger.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("logger.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "logger.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 logger.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载logger.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找logger.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用logger.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询module_centerBook.dll版本号
|
||
//func moduleCenterBookDllVersion(currentDir string) (string, error) {
|
||
// // 方案1:使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "module-centerBook.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("module-centerBook.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-centerBook.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 module-centerBook.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载module-centerBook.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找module-centerBook.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用module-centerBook.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询module_login.dll版本号
|
||
//func moduleLoginDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "module-login.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("module-login.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-login.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 module-login.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载module-login.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找module-login.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用module-login.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
//
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询module-erp.dll版本号
|
||
//func moduleErpDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "module-erp.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("module-erp.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-erp.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 module-erp.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载module-erp.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找module-erp.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用module-erp.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
//
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询module-kongfz.dll版本号
|
||
//func moduleKongfzDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "module-kongfz.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("module-kongfz.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-kongfz.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 module-kongfz.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载module-kongfz.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找module-kongfz.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用module-kongfz.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询module-taskPool.dll版本号
|
||
//func moduleTaskPoolDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "module-taskPool.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("module-taskPool.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-taskPool.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 module-taskPool.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载module-taskPool.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找module-taskPool.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用module-taskPool.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询module-verifyPrice.dll版本号
|
||
//func moduleVerifyPriceDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "module-verifyPrice.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("module-verifyPrice.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "module-verifyPrice.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 module-verifyPrice.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载module-verifyPrice.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion"
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找module-verifyPrice.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用module-verifyPrice.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询picTool.dll版本号
|
||
//func picToolDllVersion(currentDir string) (string, error) {
|
||
// // 使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "picTool.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("picTool.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "picTool.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 picTool.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载picTool.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion" // 你的函数名
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找picTool.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用picTool.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
//// 查询proxy.dll版本号
|
||
//func proxyDllVersion(currentDir string) (string, error) {
|
||
// // 方案1:使用绝对路径
|
||
// dllPath := filepath.Join(currentDir, "dll", "proxy.dll")
|
||
//
|
||
// // 判断dll文件是否存在,不存在下载新版本
|
||
// _, err := os.Stat(dllPath)
|
||
// if err != nil {
|
||
// if os.IsNotExist(err) {
|
||
// printDownload("proxy.dll文件缺失,开始下载...")
|
||
// err = downloadDLL("http://36.212.20.113:53300/api/downLoad", dllPath, "proxy.dll", "")
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("下载 proxy.dll 文件失败: %v", err)
|
||
// }
|
||
// return "", nil
|
||
// }
|
||
// }
|
||
//
|
||
// // 加载DLL
|
||
// dll, err := syscall.LoadDLL(dllPath)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("加载proxy.dll文件失败: %v", err)
|
||
// }
|
||
//
|
||
// // 查找函数
|
||
// funcName := "GetVersion" // 你的函数名
|
||
// proc, err := dll.FindProc(funcName)
|
||
// if err != nil {
|
||
// return "", fmt.Errorf("查找proxy.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
//
|
||
// // 调用函数(无参数版本)
|
||
// ret, _, err := proc.Call()
|
||
// if err != nil && err.Error() != "The operation completed successfully." {
|
||
// return "", fmt.Errorf("调用proxy.dll GetVersion 函数失败: %v", err)
|
||
// }
|
||
// str := cStr(ret)
|
||
// // 释放C字符串
|
||
// if proc, err = dll.FindProc("FreeCString"); err == nil {
|
||
// defer proc.Call(ret)
|
||
// }
|
||
// return str, nil
|
||
//}
|
||
//
|
||
////func downloadDLL(url, outputPath, filename, version string) error {
|
||
//// // 1. 确保目录存在
|
||
//// dir := filepath.Dir(outputPath)
|
||
//// if err := os.MkdirAll(dir, 0755); err != nil {
|
||
//// return fmt.Errorf("创建目录失败: %v", err)
|
||
//// }
|
||
////
|
||
//// // 2. 创建临时文件路径(避免直接操作目标文件)
|
||
//// tempPath := outputPath + ".tmp"
|
||
////
|
||
//// // 清理可能存在的旧临时文件
|
||
//// if _, err := os.Stat(tempPath); err == nil {
|
||
//// os.Remove(tempPath)
|
||
//// }
|
||
////
|
||
//// // 3. 检查目标文件是否存在
|
||
//// if _, err := os.Stat(outputPath); err == nil {
|
||
//// // 尝试重命名原文件(而不是直接删除)
|
||
//// backupPath := outputPath + ".bak"
|
||
//// if err := os.Rename(outputPath, backupPath); err != nil {
|
||
//// // 重命名失败,尝试直接删除
|
||
//// for i := 0; i < 3; i++ { // 重试3次
|
||
//// if err := os.Remove(outputPath); err == nil {
|
||
//// break
|
||
//// }
|
||
//// if i == 2 { // 最后一次尝试
|
||
//// if strings.Contains(err.Error(), "Access is denied") {
|
||
//// return fmt.Errorf("文件被其他程序占用,请关闭可能使用此文件的程序后再试: %s", outputPath)
|
||
//// }
|
||
//// return fmt.Errorf("无法删除已存在的文件: %v", err)
|
||
//// }
|
||
//// time.Sleep(1 * time.Second)
|
||
//// }
|
||
//// } else {
|
||
//// // 异步清理备份文件
|
||
//// go func() {
|
||
//// time.Sleep(30 * time.Second) // 30秒后清理
|
||
//// if _, err := os.Stat(backupPath); err == nil {
|
||
//// os.Remove(backupPath)
|
||
//// }
|
||
//// }()
|
||
//// }
|
||
//// }
|
||
////
|
||
//// // 4. 创建HTTP客户端
|
||
//// client := &http.Client{
|
||
//// Timeout: 30 * time.Minute,
|
||
//// }
|
||
////
|
||
//// // 5. 发送GET请求下载文件
|
||
//// // 注意:这里先打印下载开始信息,这行会在主函数打印版本号信息之后立即执行
|
||
//// if version == "" {
|
||
//// printDownload("正在下载: %s (版本: %s)", filename, "最新版本")
|
||
//// } else {
|
||
//// printDownload("正在下载: %s (版本: %s)", filename, version)
|
||
//// }
|
||
////
|
||
//// // 添加查询参数
|
||
//// req, err := http.NewRequest("GET", url, nil)
|
||
//// if err != nil {
|
||
//// return fmt.Errorf("创建请求失败: %v", err)
|
||
//// }
|
||
////
|
||
//// q := req.URL.Query()
|
||
//// q.Add("filename", filename)
|
||
//// if version != "" {
|
||
//// q.Add("version", version)
|
||
//// }
|
||
//// req.URL.RawQuery = q.Encode()
|
||
////
|
||
//// resp, err := client.Do(req)
|
||
//// if err != nil {
|
||
//// return fmt.Errorf("请求失败: %v", err)
|
||
//// }
|
||
//// defer resp.Body.Close()
|
||
////
|
||
//// if resp.StatusCode != http.StatusOK {
|
||
//// return fmt.Errorf("服务器返回错误状态码: %d", resp.StatusCode)
|
||
//// }
|
||
////
|
||
//// // 6. 获取文件大小
|
||
//// totalSize := resp.ContentLength
|
||
//// if totalSize > 0 {
|
||
//// fmt.Printf(ColorGray+"文件大小: %.2f MB\n"+ColorReset, float64(totalSize)/1024/1024)
|
||
//// }
|
||
////
|
||
//// // 7. 创建临时文件
|
||
//// out, err := os.OpenFile(tempPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
|
||
//// if err != nil {
|
||
//// return fmt.Errorf("创建临时文件失败: %v", err)
|
||
//// }
|
||
//// defer out.Close()
|
||
////
|
||
//// // 8. 确保下载失败时清理临时文件
|
||
//// downloadSuccess := false
|
||
//// defer func() {
|
||
//// if !downloadSuccess {
|
||
//// os.Remove(tempPath)
|
||
//// }
|
||
//// }()
|
||
////
|
||
//// // 9. 手动进度显示
|
||
//// startTime := time.Now()
|
||
//// var downloaded int64 = 0
|
||
//// var lastUpdate time.Time
|
||
//// lastUpdate = time.Now()
|
||
////
|
||
//// // 10. 创建缓冲区读取
|
||
//// buf := make([]byte, 32*1024)
|
||
//// for {
|
||
//// n, err := resp.Body.Read(buf)
|
||
//// if n > 0 {
|
||
//// // 写入临时文件
|
||
//// if _, writeErr := out.Write(buf[:n]); writeErr != nil {
|
||
//// return fmt.Errorf("写入文件失败: %v", writeErr)
|
||
//// }
|
||
////
|
||
//// // 更新下载量
|
||
//// downloaded += int64(n)
|
||
////
|
||
//// // 每500ms更新一次进度
|
||
//// if time.Since(lastUpdate) > 500*time.Millisecond || err != nil {
|
||
//// if totalSize > 0 {
|
||
//// percent := float64(downloaded) / float64(totalSize) * 100
|
||
//// fmt.Printf("\r"+ColorCyan+"下载进度: %.2f%% (%.2f/%.2f MB)"+ColorReset,
|
||
//// percent,
|
||
//// float64(downloaded)/1024/1024,
|
||
//// float64(totalSize)/1024/1024)
|
||
//// } else {
|
||
//// fmt.Printf("\r"+ColorCyan+"已下载: %.2f MB"+ColorReset, float64(downloaded)/1024/1024)
|
||
//// }
|
||
//// lastUpdate = time.Now()
|
||
//// }
|
||
//// }
|
||
////
|
||
//// if err != nil {
|
||
//// if err != io.EOF {
|
||
//// return fmt.Errorf("读取失败: %v", err)
|
||
//// }
|
||
//// break
|
||
//// }
|
||
//// }
|
||
////
|
||
//// // 下载完成,确保进度显示100%
|
||
//// if totalSize > 0 && downloaded < totalSize {
|
||
//// downloaded = totalSize
|
||
//// }
|
||
//// fmt.Printf("\r"+ColorGreen+"下载进度: 100.00%% (%.2f/%.2f MB)\n"+ColorReset,
|
||
//// float64(downloaded)/1024/1024,
|
||
//// float64(totalSize)/1024/1024)
|
||
////
|
||
//// // 11. 关闭临时文件
|
||
//// out.Close()
|
||
////
|
||
//// // 12. 验证下载的文件大小
|
||
//// if totalSize > 0 {
|
||
//// if fi, err := os.Stat(tempPath); err == nil {
|
||
//// if fi.Size() != totalSize {
|
||
//// return fmt.Errorf("文件大小不匹配: 期望 %d, 实际 %d", totalSize, fi.Size())
|
||
//// }
|
||
//// }
|
||
//// }
|
||
////
|
||
//// // 13. 将临时文件重命名为目标文件
|
||
//// for i := 0; i < 3; i++ {
|
||
//// if err := os.Rename(tempPath, outputPath); err == nil {
|
||
//// downloadSuccess = true
|
||
//// break
|
||
//// }
|
||
////
|
||
//// if i == 2 {
|
||
//// // 尝试直接复制
|
||
//// if err := copyFile(tempPath, outputPath); err != nil {
|
||
//// return fmt.Errorf("保存文件失败: %v", err)
|
||
//// }
|
||
//// downloadSuccess = true
|
||
//// }
|
||
////
|
||
//// time.Sleep(500 * time.Millisecond)
|
||
//// }
|
||
////
|
||
//// elapsed := time.Since(startTime)
|
||
//// printSuccess("下载完成: %s (耗时: %v)", filepath.Base(outputPath), elapsed.Round(time.Second))
|
||
////
|
||
//// // 14. 验证最终文件
|
||
//// if _, err := os.Stat(outputPath); err != nil {
|
||
//// return fmt.Errorf("最终文件验证失败: %v", err)
|
||
//// }
|
||
////
|
||
//// return nil
|
||
////}
|
||
//
|
||
//// 主下载函数
|
||
//func downloadDLL(url, outputPath, filename, version string) error {
|
||
// // 1. 确保目录存在
|
||
// dir := filepath.Dir(outputPath)
|
||
// if err := os.MkdirAll(dir, 0755); err != nil {
|
||
// return fmt.Errorf("创建目录失败: %v", err)
|
||
// }
|
||
//
|
||
// // 2. 创建临时文件路径
|
||
// tempPath := outputPath + ".tmp"
|
||
//
|
||
// // 3. 清理可能存在的旧临时文件
|
||
// if _, err := os.Stat(tempPath); err == nil {
|
||
// os.Remove(tempPath)
|
||
// }
|
||
//
|
||
// // 4. 检查目标文件是否存在
|
||
// if _, err := os.Stat(outputPath); err == nil {
|
||
// backupPath := outputPath + ".bak"
|
||
// if err := os.Rename(outputPath, backupPath); err != nil {
|
||
// // 重命名失败,尝试直接删除
|
||
// for i := 0; i < 3; i++ {
|
||
// if err := os.Remove(outputPath); err == nil {
|
||
// break
|
||
// }
|
||
// if i == 2 {
|
||
// if strings.Contains(err.Error(), "Access is denied") {
|
||
// return fmt.Errorf("文件被其他程序占用,请关闭可能使用此文件的程序后再试: %s", outputPath)
|
||
// }
|
||
// return fmt.Errorf("无法删除已存在的文件: %v", err)
|
||
// }
|
||
// time.Sleep(1 * time.Second)
|
||
// }
|
||
// } else {
|
||
// // 异步清理备份文件
|
||
// go func() {
|
||
// time.Sleep(30 * time.Second)
|
||
// if _, err := os.Stat(backupPath); err == nil {
|
||
// os.Remove(backupPath)
|
||
// }
|
||
// }()
|
||
// }
|
||
// }
|
||
//
|
||
// // 5. 打印下载信息
|
||
// if version == "" {
|
||
// printDownload("正在下载: %s (版本: 最新版本)", filename)
|
||
// } else {
|
||
// printDownload("正在下载: %s (版本: %s)", filename, version)
|
||
// }
|
||
//
|
||
// // 6. 首先尝试获取文件大小信息(HEAD请求)
|
||
// headClient := &http.Client{
|
||
// Timeout: 10 * time.Second,
|
||
// }
|
||
//
|
||
// headReq, err := http.NewRequest("HEAD", url, nil)
|
||
// if err != nil {
|
||
// printError("创建HEAD请求失败,使用默认超时设置: %v", err)
|
||
// } else {
|
||
// // 添加查询参数
|
||
// q := headReq.URL.Query()
|
||
// q.Add("filename", filename)
|
||
// if version != "" {
|
||
// q.Add("version", version)
|
||
// }
|
||
// headReq.URL.RawQuery = q.Encode()
|
||
// headReq.Header.Set("User-Agent", "DLL-Downloader/1.0")
|
||
//
|
||
// resp, err := headClient.Do(headReq)
|
||
// if err == nil && resp.StatusCode == http.StatusOK {
|
||
// if contentLength := resp.ContentLength; contentLength > 0 {
|
||
// fmt.Printf(ColorGray+"获取到文件大小: %.2f MB\n"+ColorReset,
|
||
// float64(contentLength)/1024/1024)
|
||
// }
|
||
// resp.Body.Close()
|
||
// }
|
||
// }
|
||
//
|
||
// // 7. 创建长时间下载的HTTP客户端
|
||
// // 使用自定义Transport,不设置Client.Timeout,改用context控制
|
||
// transport := &http.Transport{
|
||
// Proxy: http.ProxyFromEnvironment,
|
||
// DialContext: (&net.Dialer{
|
||
// Timeout: 30 * time.Second,
|
||
// KeepAlive: 30 * time.Second,
|
||
// DualStack: true,
|
||
// }).DialContext,
|
||
// ForceAttemptHTTP2: true,
|
||
// MaxIdleConns: 100,
|
||
// MaxIdleConnsPerHost: 10,
|
||
// IdleConnTimeout: 90 * time.Second,
|
||
// TLSHandshakeTimeout: 15 * time.Second,
|
||
// ExpectContinueTimeout: 5 * time.Second,
|
||
// ResponseHeaderTimeout: 30 * time.Second,
|
||
// ReadBufferSize: 128 * 1024, // 128KB
|
||
// WriteBufferSize: 128 * 1024,
|
||
// // 禁用读写超时,通过活动检测控制
|
||
// }
|
||
//
|
||
// client := &http.Client{
|
||
// Transport: transport,
|
||
// // 重要:不设置Timeout,使用context控制
|
||
// }
|
||
//
|
||
// // 8. 创建下载请求
|
||
// // 使用3小时的context超时,但通过活动检测防止死连接
|
||
// ctx, cancel := context.WithTimeout(context.Background(), 3*time.Hour)
|
||
// defer cancel()
|
||
//
|
||
// req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建请求失败: %v", err)
|
||
// }
|
||
//
|
||
// // 添加查询参数
|
||
// q := req.URL.Query()
|
||
// q.Add("filename", filename)
|
||
// if version != "" {
|
||
// q.Add("version", version)
|
||
// }
|
||
// req.URL.RawQuery = q.Encode()
|
||
//
|
||
// // 添加请求头
|
||
// req.Header.Set("User-Agent", "DLL-Downloader/1.0")
|
||
// req.Header.Set("Accept", "*/*")
|
||
// req.Header.Set("Accept-Encoding", "gzip, deflate")
|
||
// req.Header.Set("Connection", "keep-alive")
|
||
//
|
||
// // 9. 发送请求
|
||
// resp, err := client.Do(req)
|
||
// if err != nil {
|
||
// if strings.Contains(err.Error(), "context deadline exceeded") {
|
||
// return fmt.Errorf("连接超时,请检查网络连接: %v", err)
|
||
// }
|
||
// return fmt.Errorf("请求失败: %v", err)
|
||
// }
|
||
// defer resp.Body.Close()
|
||
//
|
||
// if resp.StatusCode != http.StatusOK {
|
||
// body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024))
|
||
// return fmt.Errorf("服务器返回错误: %d - %s", resp.StatusCode, string(body))
|
||
// }
|
||
//
|
||
// // 10. 获取文件大小
|
||
// totalSize := resp.ContentLength
|
||
// if totalSize > 0 {
|
||
// fmt.Printf(ColorGray+"文件大小: %.2f MB\n"+ColorReset, float64(totalSize)/1024/1024)
|
||
//
|
||
// // 根据文件大小提供预估时间
|
||
// // 假设最低速度 50KB/s
|
||
// minSpeed := 50.0 * 1024
|
||
// estimatedTime := time.Duration(float64(totalSize)/minSpeed) * time.Second
|
||
// if estimatedTime > 30*time.Second {
|
||
// fmt.Printf(ColorGray+"预估下载时间: %v (基于50KB/s最低速度)\n"+ColorReset,
|
||
// estimatedTime.Round(time.Second))
|
||
// }
|
||
// } else {
|
||
// fmt.Println(ColorGray + "文件大小: 未知" + ColorReset)
|
||
// }
|
||
//
|
||
// // 11. 创建临时文件
|
||
// out, err := os.OpenFile(tempPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0755)
|
||
// if err != nil {
|
||
// return fmt.Errorf("创建临时文件失败: %v", err)
|
||
// }
|
||
// defer out.Close()
|
||
//
|
||
// // 12. 确保下载失败时清理临时文件
|
||
// downloadSuccess := false
|
||
// defer func() {
|
||
// if !downloadSuccess {
|
||
// os.Remove(tempPath)
|
||
// }
|
||
// }()
|
||
//
|
||
// // 13. 活动检测机制
|
||
// activityCh := make(chan time.Time, 100) // 缓冲通道,避免阻塞
|
||
// var lastActivity time.Time
|
||
// lastActivity = time.Now()
|
||
//
|
||
// // 创建活动检测的reader
|
||
// activityReader := &activityReader{
|
||
// reader: resp.Body,
|
||
// activityCh: activityCh,
|
||
// activityPtr: &lastActivity,
|
||
// }
|
||
//
|
||
// // 启动活动检测goroutine
|
||
// activityCtx, activityCancel := context.WithCancel(context.Background())
|
||
// defer activityCancel()
|
||
//
|
||
// go func() {
|
||
// ticker := time.NewTicker(30 * time.Second) // 每30秒检查一次活动
|
||
// defer ticker.Stop()
|
||
//
|
||
// for {
|
||
// select {
|
||
// case <-activityCtx.Done():
|
||
// return
|
||
// case activityTime := <-activityCh:
|
||
// lastActivity = activityTime
|
||
// case <-ticker.C:
|
||
// // 检查最近60秒内是否有活动
|
||
// if time.Since(lastActivity) > 60*time.Second {
|
||
// printError("下载活动超时,60秒内没有收到数据")
|
||
// cancel() // 取消主context
|
||
// return
|
||
// }
|
||
// }
|
||
// }
|
||
// }()
|
||
//
|
||
// // 14. 下载进度显示
|
||
// startTime := time.Now()
|
||
// var downloaded int64 = 0
|
||
// var lastUpdate time.Time
|
||
// lastUpdate = time.Now()
|
||
//
|
||
// // 15. 创建缓冲区
|
||
// buf := make([]byte, 128*1024) // 128KB缓冲区
|
||
//
|
||
// // 显示初始进度
|
||
// fmt.Print(ColorCyan + "下载进度: 0.00% (0.00/0.00 MB)" + ColorReset)
|
||
//
|
||
// for {
|
||
// // 检查context是否被取消
|
||
// select {
|
||
// case <-ctx.Done():
|
||
// return fmt.Errorf("下载被取消: %v", ctx.Err())
|
||
// default:
|
||
// // 继续下载
|
||
// }
|
||
//
|
||
// n, err := activityReader.Read(buf)
|
||
// if n > 0 {
|
||
// // 写入临时文件
|
||
// if _, writeErr := out.Write(buf[:n]); writeErr != nil {
|
||
// return fmt.Errorf("写入文件失败: %v", writeErr)
|
||
// }
|
||
//
|
||
// // 更新下载量
|
||
// downloaded += int64(n)
|
||
//
|
||
// // 更新进度显示(每秒最多更新一次)
|
||
// if time.Since(lastUpdate) > 1*time.Second || err != nil {
|
||
// if totalSize > 0 {
|
||
// percent := float64(downloaded) / float64(totalSize) * 100
|
||
// elapsed := time.Since(startTime).Seconds()
|
||
// speed := 0.0
|
||
// if elapsed > 0 {
|
||
// speed = float64(downloaded) / elapsed / 1024 / 1024
|
||
// }
|
||
//
|
||
// // 计算剩余时间
|
||
// remaining := time.Duration(0)
|
||
// if speed > 0 && downloaded > 0 {
|
||
// remainingSecs := float64(totalSize-downloaded) / (float64(downloaded) / elapsed)
|
||
// remaining = time.Duration(remainingSecs) * time.Second
|
||
// }
|
||
//
|
||
// // 清除当前行并显示进度
|
||
// fmt.Printf("\r\033[K"+ColorCyan+"下载进度: %.2f%% (%.2f/%.2f MB) 速度: %.2f MB/s 剩余: %v"+ColorReset,
|
||
// percent,
|
||
// float64(downloaded)/1024/1024,
|
||
// float64(totalSize)/1024/1024,
|
||
// speed,
|
||
// remaining.Round(time.Second))
|
||
// } else {
|
||
// // 未知文件大小的情况
|
||
// elapsed := time.Since(startTime).Seconds()
|
||
// speed := 0.0
|
||
// if elapsed > 0 {
|
||
// speed = float64(downloaded) / elapsed / 1024 / 1024
|
||
// }
|
||
// fmt.Printf("\r\033[K"+ColorCyan+"已下载: %.2f MB 速度: %.2f MB/s"+ColorReset,
|
||
// float64(downloaded)/1024/1024,
|
||
// speed)
|
||
// }
|
||
// lastUpdate = time.Now()
|
||
// }
|
||
// }
|
||
//
|
||
// if err != nil {
|
||
// if err == io.EOF {
|
||
// break
|
||
// }
|
||
// // 检查是否是context取消的错误
|
||
// if ctx.Err() != nil {
|
||
// return fmt.Errorf("下载中断: %v", ctx.Err())
|
||
// }
|
||
// return fmt.Errorf("读取数据失败: %v", err)
|
||
// }
|
||
// }
|
||
//
|
||
// // 16. 下载完成,显示最终进度
|
||
// if totalSize > 0 && downloaded < totalSize {
|
||
// downloaded = totalSize // 确保显示100%
|
||
// }
|
||
//
|
||
// if totalSize > 0 {
|
||
// fmt.Printf("\r\033[K"+ColorGreen+"下载完成: 100.00%% (%.2f/%.2f MB)\n"+ColorReset,
|
||
// float64(downloaded)/1024/1024,
|
||
// float64(totalSize)/1024/1024)
|
||
// } else {
|
||
// fmt.Printf("\r\033[K"+ColorGreen+"下载完成: %.2f MB\n"+ColorReset,
|
||
// float64(downloaded)/1024/1024)
|
||
// }
|
||
//
|
||
// // 停止活动检测
|
||
// activityCancel()
|
||
//
|
||
// // 17. 验证下载的文件大小
|
||
// if totalSize > 0 {
|
||
// fi, err := os.Stat(tempPath)
|
||
// if err != nil {
|
||
// return fmt.Errorf("无法验证下载文件: %v", err)
|
||
// }
|
||
// if fi.Size() != totalSize {
|
||
// return fmt.Errorf("文件大小不匹配: 期望 %d 字节, 实际 %d 字节", totalSize, fi.Size())
|
||
// }
|
||
// }
|
||
//
|
||
// // 18. 将临时文件重命名为目标文件
|
||
// maxRetries := 5
|
||
// for i := 0; i < maxRetries; i++ {
|
||
// if err := os.Rename(tempPath, outputPath); err == nil {
|
||
// downloadSuccess = true
|
||
// break
|
||
// }
|
||
//
|
||
// if i == maxRetries-1 {
|
||
// // 最后一次尝试:使用复制方式
|
||
// if err := copyFile(tempPath, outputPath); err != nil {
|
||
// return fmt.Errorf("保存文件失败: %v", err)
|
||
// }
|
||
// downloadSuccess = true
|
||
// } else {
|
||
// // 等待后重试
|
||
// time.Sleep(500 * time.Millisecond * time.Duration(i+1))
|
||
// }
|
||
// }
|
||
//
|
||
// // 19. 验证最终文件
|
||
// fi, err := os.Stat(outputPath)
|
||
// if err != nil {
|
||
// return fmt.Errorf("最终文件验证失败: %v", err)
|
||
// }
|
||
//
|
||
// elapsed := time.Since(startTime)
|
||
// speed := float64(fi.Size()) / elapsed.Seconds() / 1024 / 1024
|
||
// printSuccess("下载完成: %s (大小: %.2f MB, 耗时: %v, 平均速度: %.2f MB/s)",
|
||
// filepath.Base(outputPath),
|
||
// float64(fi.Size())/1024/1024,
|
||
// elapsed.Round(time.Second),
|
||
// speed)
|
||
//
|
||
// return nil
|
||
//}
|
||
//
|
||
//// 活动检测读取器
|
||
//type activityReader struct {
|
||
// reader io.Reader
|
||
// activityCh chan<- time.Time
|
||
// activityPtr *time.Time
|
||
//}
|
||
//
|
||
//func (r *activityReader) Read(p []byte) (n int, err error) {
|
||
// n, err = r.reader.Read(p)
|
||
// if n > 0 {
|
||
// now := time.Now()
|
||
// r.activityCh <- now
|
||
// if r.activityPtr != nil {
|
||
// *r.activityPtr = now
|
||
// }
|
||
// }
|
||
// return
|
||
//}
|
||
//
|
||
//// 辅助函数:复制文件
|
||
//func copyFile(src, dst string) error {
|
||
// source, err := os.Open(src)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// defer source.Close()
|
||
//
|
||
// destination, err := os.Create(dst)
|
||
// if err != nil {
|
||
// return err
|
||
// }
|
||
// defer destination.Close()
|
||
//
|
||
// _, err = io.Copy(destination, source)
|
||
// return err
|
||
//}
|
||
//
|
||
//// 辅助函数:检查文件是否被占用
|
||
//func isFileLocked(filepath string) bool {
|
||
// file, err := os.OpenFile(filepath, os.O_RDWR, 0666)
|
||
// if err != nil {
|
||
// return strings.Contains(err.Error(), "The process cannot access the file")
|
||
// }
|
||
// file.Close()
|
||
// return false
|
||
//}
|