@@ -5668,6 +5668,8 @@ pub fn close_antigravity_instances(
56685668 user_data_dirs : & [ String ] ,
56695669 timeout_secs : u64 ,
56705670) -> Result < ( ) , String > {
5671+ #[ cfg( target_os = "windows" ) ]
5672+ let _ = timeout_secs;
56715673 let default_dir = crate :: modules:: instance:: get_default_user_data_dir ( )
56725674 . ok ( )
56735675 . map ( |value| normalize_path_for_compare ( & value. to_string_lossy ( ) ) )
@@ -5693,15 +5695,95 @@ pub fn close_antigravity_instances(
56935695 default_dir. as_deref ( ) ,
56945696 )
56955697 } ,
5696- None ,
5697- None ,
5698+ Some ( request_antigravity_graceful_close as fn ( u32 ) ) ,
5699+ Some ( 2 ) ,
56985700 #[ cfg( target_os = "windows" ) ]
56995701 Some ( log_antigravity_process_details_for_pids as fn ( & [ u32 ] ) ) ,
57005702 #[ cfg( not( target_os = "windows" ) ) ]
57015703 None ,
57025704 )
57035705}
57045706
5707+ fn request_antigravity_graceful_close ( pid : u32 ) {
5708+ if pid == 0 || !is_pid_running ( pid) {
5709+ return ;
5710+ }
5711+
5712+ #[ cfg( target_os = "macos" ) ]
5713+ {
5714+ let script = format ! (
5715+ "tell application \" System Events\" to set frontmost of (first process whose unix id is {}) to true\n \
5716+ tell application \" System Events\" to keystroke \" q\" using command down",
5717+ pid
5718+ ) ;
5719+ match Command :: new ( "osascript" ) . args ( [ "-e" , & script] ) . output ( ) {
5720+ Ok ( output) => {
5721+ if output. status . success ( ) {
5722+ crate :: modules:: logger:: log_info ( & format ! (
5723+ "[AG Close] 已发送优雅退出请求 pid={}" ,
5724+ pid
5725+ ) ) ;
5726+ } else {
5727+ let stderr = String :: from_utf8_lossy ( & output. stderr ) ;
5728+ crate :: modules:: logger:: log_warn ( & format ! (
5729+ "[AG Close] 优雅退出失败 pid={} err={}" ,
5730+ pid,
5731+ stderr. trim( )
5732+ ) ) ;
5733+ }
5734+ }
5735+ Err ( err) => {
5736+ crate :: modules:: logger:: log_warn ( & format ! (
5737+ "[AG Close] 调用 osascript 失败 pid={} err={}" ,
5738+ pid, err
5739+ ) ) ;
5740+ }
5741+ }
5742+ }
5743+
5744+ #[ cfg( target_os = "windows" ) ]
5745+ {
5746+ use std:: os:: windows:: process:: CommandExt ;
5747+
5748+ crate :: modules:: logger:: log_info ( & format ! ( "[AG Close] graceful taskkill start pid={}" , pid) ) ;
5749+ let output = Command :: new ( "taskkill" )
5750+ . args ( [ "/PID" , & pid. to_string ( ) , "/T" ] )
5751+ . creation_flags ( CREATE_NO_WINDOW )
5752+ . stdin ( Stdio :: null ( ) )
5753+ . stdout ( Stdio :: null ( ) )
5754+ . stderr ( Stdio :: null ( ) )
5755+ . output ( ) ;
5756+ match output {
5757+ Ok ( value) => {
5758+ if value. status . success ( ) {
5759+ crate :: modules:: logger:: log_info ( & format ! (
5760+ "[AG Close] graceful taskkill success pid={} status={}" ,
5761+ pid, value. status
5762+ ) ) ;
5763+ } else {
5764+ crate :: modules:: logger:: log_warn ( & format ! (
5765+ "[AG Close] graceful taskkill failed pid={} status={}" ,
5766+ pid, value. status
5767+ ) ) ;
5768+ }
5769+ }
5770+ Err ( err) => {
5771+ crate :: modules:: logger:: log_warn ( & format ! (
5772+ "[AG Close] graceful taskkill error pid={} err={}" ,
5773+ pid, err
5774+ ) ) ;
5775+ }
5776+ }
5777+ }
5778+
5779+ #[ cfg( target_os = "linux" ) ]
5780+ {
5781+ let _ = Command :: new ( "kill" )
5782+ . args ( [ "-15" , & pid. to_string ( ) ] )
5783+ . output ( ) ;
5784+ }
5785+ }
5786+
57055787pub fn close_pid ( pid : u32 , timeout_secs : u64 ) -> Result < ( ) , String > {
57065788 if pid == 0 {
57075789 return Err ( "PID 无效,无法关闭进程" . to_string ( ) ) ;
0 commit comments