package fileops import ( "errors" "time" "golang.org/x/sys/windows" ) func renameReplacing(oldPath, newPath string) error { source, err := windows.UTF16PtrFromString(oldPath) if err != nil { return err } target, err := windows.UTF16PtrFromString(newPath) if err != nil { return err } // Concurrent replacement, short-lived readers and antivirus scans can hold // an NTFS destination briefly. Retry only transient conflicts, preserving // both files until the kernel completes one atomic replacement. deadline := time.Now().Add(time.Second) for { err := windows.MoveFileEx(source, target, windows.MOVEFILE_REPLACE_EXISTING|windows.MOVEFILE_WRITE_THROUGH) if err == nil || time.Now().After(deadline) || (!errors.Is(err, windows.ERROR_SHARING_VIOLATION) && !errors.Is(err, windows.ERROR_LOCK_VIOLATION) && !errors.Is(err, windows.ERROR_ACCESS_DENIED)) { return err } time.Sleep(20 * time.Millisecond) } }