@@ -2,6 +2,7 @@ use std::io;
22use std:: path:: { Path , PathBuf } ;
33use std:: str:: Utf8Error ;
44
5+ use fs_err:: File ;
56use thiserror:: Error ;
67
78#[ cfg( all( windows, target_arch = "x86" ) ) ]
@@ -128,18 +129,26 @@ impl Launcher {
128129 /// On Unix, this always returns [`Error::NotWindows`]. Trampolines are a Windows-specific
129130 /// feature and cannot be written on other platforms.
130131 #[ cfg( not( windows) ) ]
131- pub fn write_to_file ( self , _file_path : & Path , _is_gui : bool ) -> Result < ( ) , Error > {
132+ pub fn write_to_file ( self , _file : & mut File , _is_gui : bool ) -> Result < ( ) , Error > {
132133 Err ( Error :: NotWindows )
133134 }
134135
135136 /// Write this trampoline launcher to a file.
136137 #[ cfg( windows) ]
137- pub fn write_to_file ( self , file_path : & Path , is_gui : bool ) -> Result < ( ) , Error > {
138+ pub fn write_to_file ( self , file : & mut File , is_gui : bool ) -> Result < ( ) , Error > {
139+ use std:: io:: Write ;
138140 use uv_fs:: Simplified ;
141+
139142 let python_path = self . python_path . simplified_display ( ) . to_string ( ) ;
140143
144+ // Create temporary file for the base launcher
145+ let temp_dir = tempfile:: TempDir :: new ( ) ?;
146+ let temp_file = temp_dir
147+ . path ( )
148+ . join ( format ! ( "uv-trampoline-{}.exe" , std:: process:: id( ) ) ) ;
149+
141150 // Write the launcher binary
142- fs_err:: write ( file_path , get_launcher_bin ( is_gui) ?) ?;
151+ fs_err:: write ( & temp_file , get_launcher_bin ( is_gui) ?) ?;
143152
144153 // Write resources
145154 let resources = & [
@@ -152,11 +161,18 @@ impl Launcher {
152161 if let Some ( script_data) = self . script_data {
153162 let mut all_resources = resources. to_vec ( ) ;
154163 all_resources. push ( ( RESOURCE_SCRIPT_DATA , & script_data) ) ;
155- write_resources ( file_path , & all_resources) ?;
164+ write_resources ( & temp_file , & all_resources) ?;
156165 } else {
157- write_resources ( file_path , resources) ?;
166+ write_resources ( & temp_file , resources) ?;
158167 }
159168
169+ // Read back the complete file
170+ let launcher = fs_err:: read ( & temp_file) ?;
171+ fs_err:: remove_file ( & temp_file) ?;
172+
173+ // Then write it to the handle
174+ file. write_all ( & launcher) ?;
175+
160176 Ok ( ( ) )
161177 }
162178
@@ -403,6 +419,9 @@ pub fn windows_script_launcher(
403419 write_resources ( & temp_file, resources) ?;
404420
405421 // Read back the complete file
422+ // TODO(zanieb): It's weird that we write/read from a temporary file here because in the main
423+ // usage at `write_script_entrypoints` we do the same thing again. We should refactor these
424+ // to avoid repeated work.
406425 let launcher = fs_err:: read ( & temp_file) ?;
407426 fs_err:: remove_file ( temp_file) ?;
408427
0 commit comments