修复: SFTP连接首拉不显示与传输挂起

- watcher握手期伪触发致幻影本地列表,根因修复
- 连接探测2.5s超时竞速,握手10s预算
- 30s保活自动掐死半开连接,取连接时剔除已断开
- 副本命名与进度计数抽公共,下载缓存清理去重
This commit is contained in:
lxy
2026-09-15 22:26:22 +08:00
parent e7a2c5148e
commit 6ea9d9ac99
9 changed files with 731 additions and 125 deletions
+13 -19
View File
@@ -240,7 +240,7 @@ func replaceExecutableFile(newFilePath, execPath string) error {
}
// Unix-like: 直接替换
if err := copyFile(newFilePath, execPath); err != nil {
if err := common.CopyFile(newFilePath, execPath); err != nil {
return fmt.Errorf("复制文件失败: %v", err)
}
return os.Chmod(execPath, 0755)
@@ -256,13 +256,13 @@ func replaceExecutableFileWindows(newFilePath, execPath string) error {
os.Remove(newExecPathTemp)
// 复制新文件到临时位置
if err := copyFile(newFilePath, newExecPathTemp); err != nil {
if err := common.CopyFile(newFilePath, newExecPathTemp); err != nil {
return fmt.Errorf("复制新文件失败: %v", err)
}
// 尝试重命名当前文件(如果失败,说明文件正在使用)
if err := os.Rename(execPath, oldExecPath); err != nil {
return nil
return fmt.Errorf("当前文件正在使用,无法替换: %w", err)
}
// 替换文件
@@ -350,7 +350,7 @@ func rollbackFromBackup(backupPath string) error {
if err != nil {
return err
}
return copyFile(backupPath, execPath)
return common.CopyFile(backupPath, execPath)
}
// BackupApplication 备份当前应用
@@ -369,27 +369,21 @@ func BackupApplication() (string, error) {
backupFileName := fmt.Sprintf("u-desk-backup-%s%s", timestamp, filepath.Ext(execPath))
backupPath := filepath.Join(backupDir, backupFileName)
if err := copyFile(execPath, backupPath); err != nil {
if err := common.CopyFile(execPath, backupPath); err != nil {
return "", fmt.Errorf("复制文件失败: %v", err)
}
return backupPath, nil
}
// copyFile 复制文件
func copyFile(src, dst string) error {
sourceFile, err := os.Open(src)
// ReplacePendingFile 启动时完成上次更新遗留的 exe 替换。
// 此时进程刚启动,exe 文件无占用,可安全完成上次因文件占用未完成的替换,
// 并清理残留的 .old 备份。
func ReplacePendingFile() {
execPath, err := os.Executable()
if err != nil {
return err
return
}
defer sourceFile.Close()
destFile, err := os.Create(dst)
if err != nil {
return err
}
defer destFile.Close()
_, err = destFile.ReadFrom(sourceFile)
return err
_ = replacePendingFile(execPath) // 完成遗留的 .new -> exe 替换
os.Remove(execPath + ".old") // 清理残留备份
}