I've found a workaround for this bug. It's not pretty, but seems to work.
It is based on the observation that "Copy Files" dialog is a top-level window belonging to the same process as the setup. Thus, we enumerate top-level windows, looking for one from the same process whose handle is different from HWNDPARENT. When found, we kill its thread with TerminateThread(). I know this is brutal and not recommended, but there seems to be no other way. Sending a WM_CLOSE message to this window changes dialog's title to "Canceling..." , but does not close it.
Function VistaCopyFilesWorkaround
;get PID into $R1
System::Call "kernel32::GetCurrentProcessId() i.R1"
;define callback for EnumWindows
System::Get "(i.r1, i) iss"
Pop $R0
System::Call "user32::EnumWindows(k R0, i) i.s"
loop:
Pop $0
StrCmp $0 "callback1" 0 done
System::Call "user32::GetWindowThreadProcessId(i r1, *i .r2) i.r3"
;hwnd=$1, process ID=$2, thread ID=$3
StrCpy $0 "1" ; callback's return value (1=continue enumeration)
IntCmp $2 $R1 0 onceagain onceagain
;same process, check HWND
IntCmp $HWNDPARENT $1 onceagain 0 0
;different HWND found, try to close
System::Call "kernel32::OpenThread(i 1, i 0, i $3) i.r4"
System::Call "kernel32::TerminateThread(i $4, i 0)"
StrCpy $0 "0" ; callback's return value (0=break enumeration)
onceagain:
Push $0
System::Call "$R0"
Goto loop
done:
System::Free $R0
FunctionEnd
Call this function after CopyFiles.
Hope this helps someone 😉