@@ -265,40 +265,42 @@ def _install_zip_archive(archive_path: Path, target_xray_path: Path) -> None:
265265
266266 backup_dir = temp_dir / "_install_backup"
267267 backup_dir .mkdir (parents = True , exist_ok = True )
268- staged_targets : list [tuple [Path , Path , Path | None ]] = []
269-
270- temp_target = target_xray_path .with_suffix (".exe.new" )
271- shutil .copy2 (new_xray , temp_target )
272- backup_copy : Path | None = None
273- if target_xray_path .exists ():
274- backup_copy = backup_dir / target_xray_path .name
275- shutil .copy2 (target_xray_path , backup_copy )
276- staged_targets .append ((target_xray_path , temp_target , backup_copy ))
277-
278- for optional_name in ("geoip.dat" , "geosite.dat" , "wintun.dll" ):
279- src = _find_file (temp_dir , optional_name )
280- if src :
281- dest = target_dir / optional_name
282- staged = temp_dir / f"{ optional_name } .new"
283- shutil .copy2 (src , staged )
284- backup_copy = None
285- if dest .exists ():
286- backup_copy = backup_dir / optional_name
287- shutil .copy2 (dest , backup_copy )
288- staged_targets .append ((dest , staged , backup_copy ))
289-
290- replaced_targets : list [tuple [Path , Path | None ]] = []
291- try :
292- for dest , staged , backup_copy in staged_targets :
293- staged .replace (dest )
294- replaced_targets .append ((dest , backup_copy ))
295- except Exception :
296- for dest , backup_copy in reversed (replaced_targets ):
297- if backup_copy is not None :
298- shutil .copy2 (backup_copy , dest )
299- elif dest .exists ():
300- dest .unlink ()
301- raise
268+ with tempfile .TemporaryDirectory (prefix = ".xray_install_" , dir = target_dir ) as stage_dir_str :
269+ stage_dir = Path (stage_dir_str )
270+ staged_targets : list [tuple [Path , Path , Path | None ]] = []
271+
272+ staged_xray = stage_dir / target_xray_path .name
273+ shutil .copy2 (new_xray , staged_xray )
274+ backup_copy : Path | None = None
275+ if target_xray_path .exists ():
276+ backup_copy = backup_dir / target_xray_path .name
277+ shutil .copy2 (target_xray_path , backup_copy )
278+ staged_targets .append ((target_xray_path , staged_xray , backup_copy ))
279+
280+ for optional_name in ("geoip.dat" , "geosite.dat" , "wintun.dll" ):
281+ src = _find_file (temp_dir , optional_name )
282+ if src :
283+ dest = target_dir / optional_name
284+ staged = stage_dir / optional_name
285+ shutil .copy2 (src , staged )
286+ backup_copy = None
287+ if dest .exists ():
288+ backup_copy = backup_dir / optional_name
289+ shutil .copy2 (dest , backup_copy )
290+ staged_targets .append ((dest , staged , backup_copy ))
291+
292+ replaced_targets : list [tuple [Path , Path | None ]] = []
293+ try :
294+ for dest , staged , backup_copy in staged_targets :
295+ staged .replace (dest )
296+ replaced_targets .append ((dest , backup_copy ))
297+ except Exception :
298+ for dest , backup_copy in reversed (replaced_targets ):
299+ if backup_copy is not None :
300+ shutil .copy2 (backup_copy , dest )
301+ elif dest .exists ():
302+ dest .unlink ()
303+ raise
302304
303305 original_xray = staged_targets [0 ][2 ]
304306 if original_xray is not None :
0 commit comments