@@ -268,6 +268,36 @@ fn write_step_bat(script: &str) -> Result<PathBuf, String> {
268268 Ok ( bat)
269269}
270270
271+ /// CREATE_NO_WINDOW:所有子进程都不该弹出控制台窗口(烧录、环境探测、
272+ /// 取消时的 taskkill 同理),否则取消烧录会闪出黑窗。
273+ const CREATE_NO_WINDOW : u32 = 0x08000000 ;
274+
275+ /// 统一的 IDF 子进程启动样板:写临时 bat → 剥离 MSYS 变量 → 双管道 spawn。
276+ /// 错误以原始 `io::Error` 返回,由调用方按其上下文格式化文案。
277+ fn spawn_idf_bat ( cwd : & str , script : & str ) -> Result < Child , std:: io:: Error > {
278+ let bat = write_step_bat ( script) . map_err ( std:: io:: Error :: other) ?;
279+ let bat_path = bat. to_string_lossy ( ) . to_string ( ) ;
280+ let mut cmd = Command :: new ( "cmd" ) ;
281+ cmd. arg ( "/C" )
282+ . arg ( & bat_path)
283+ . current_dir ( cwd)
284+ . env ( "PYTHONUNBUFFERED" , "1" )
285+ // 从 Git Bash 启动时这些变量会让 export/activate 脚本拒绝执行。
286+ . env_remove ( "MSYSTEM" )
287+ . env_remove ( "MSYS" )
288+ . env_remove ( "MINGW_PREFIX" )
289+ . env_remove ( "MINGW_CHOST" )
290+ . env_remove ( "MSYSTEM_CHOST" )
291+ . stdout ( Stdio :: piped ( ) )
292+ . stderr ( Stdio :: piped ( ) ) ;
293+ #[ cfg( windows) ]
294+ {
295+ use std:: os:: windows:: process:: CommandExt ;
296+ cmd. creation_flags ( CREATE_NO_WINDOW ) ;
297+ }
298+ cmd. spawn ( )
299+ }
300+
271301/// Runs one raw cmd script (blocking). Returns:
272302/// - Ok(true) success (exit 0)
273303/// - Ok(false) non-zero exit
@@ -285,21 +315,7 @@ fn run_cmd(
285315 script : & str ,
286316 cwd : & str ,
287317) -> Result < bool , String > {
288- let bat = write_step_bat ( script) ?;
289- let bat_path = bat. to_string_lossy ( ) . to_string ( ) ;
290- let mut child = Command :: new ( "cmd" )
291- . arg ( "/C" )
292- . arg ( & bat_path)
293- . current_dir ( cwd)
294- . env ( "PYTHONUNBUFFERED" , "1" )
295- . env_remove ( "MSYSTEM" )
296- . env_remove ( "MSYS" )
297- . env_remove ( "MINGW_PREFIX" )
298- . env_remove ( "MINGW_CHOST" )
299- . env_remove ( "MSYSTEM_CHOST" )
300- . stdout ( Stdio :: piped ( ) )
301- . stderr ( Stdio :: piped ( ) )
302- . spawn ( )
318+ let mut child = spawn_idf_bat ( cwd, script)
303319 . map_err ( |e| format ! ( "Failed to start {}: {}" , stage, e) ) ?;
304320
305321 let stdout = child. stdout . take ( ) ;
@@ -538,9 +554,14 @@ pub async fn esp_flash_cancel(handle: tauri::State<'_, EspHandle>) -> Result<(),
538554 if let Some ( mut c) = child {
539555 let pid = c. id ( ) ;
540556 let _ = c. kill ( ) ;
541- let _ = Command :: new ( "taskkill" )
542- . args ( [ "/PID" , & pid. to_string ( ) , "/T" , "/F" ] )
543- . output ( ) ;
557+ let mut cmd = Command :: new ( "taskkill" ) ;
558+ cmd. args ( [ "/PID" , & pid. to_string ( ) , "/T" , "/F" ] ) ;
559+ #[ cfg( windows) ]
560+ {
561+ use std:: os:: windows:: process:: CommandExt ;
562+ cmd. creation_flags ( CREATE_NO_WINDOW ) ;
563+ }
564+ let _ = cmd. output ( ) ;
544565 }
545566 Ok ( ( ) )
546567}
@@ -738,25 +759,7 @@ fn run_probe(python: &str, activate: &Path, idf_path: &str) -> (bool, String) {
738759 python,
739760 activate. to_string_lossy( )
740761 ) ;
741- let bat = match write_step_bat ( & script) {
742- Ok ( b) => b,
743- Err ( e) => return ( false , e) ,
744- } ;
745- let bat_path = bat. to_string_lossy ( ) . to_string ( ) ;
746- let mut child = match Command :: new ( "cmd" )
747- . arg ( "/C" )
748- . arg ( & bat_path)
749- . current_dir ( idf_path)
750- . env ( "PYTHONUNBUFFERED" , "1" )
751- . env_remove ( "MSYSTEM" )
752- . env_remove ( "MSYS" )
753- . env_remove ( "MINGW_PREFIX" )
754- . env_remove ( "MINGW_CHOST" )
755- . env_remove ( "MSYSTEM_CHOST" )
756- . stdout ( Stdio :: piped ( ) )
757- . stderr ( Stdio :: piped ( ) )
758- . spawn ( )
759- {
762+ let mut child = match spawn_idf_bat ( idf_path, & script) {
760763 Ok ( c) => c,
761764 Err ( e) => return ( false , format ! ( "启动失败: {}" , e) ) ,
762765 } ;
0 commit comments