@@ -18,7 +18,7 @@ use tracing_subscriber::util::SubscriberInitExt;
1818use sentry:: integrations:: tracing:: EventFilter ;
1919use sentry:: ClientInitGuard ;
2020use windows:: Win32 :: System :: Console :: AllocConsole ;
21- use windows:: Win32 :: System :: Console :: AttachConsole ;
21+ use windows:: Win32 :: System :: Console :: { AttachConsole } ;
2222use single_instance:: SingleInstance ;
2323use windows_elevate:: { check_elevated, elevate} ;
2424
@@ -202,34 +202,84 @@ fn kill_other_instances() -> Result<(), Box<dyn std::error::Error>> {
202202 }
203203
204204 let stdout = String :: from_utf8_lossy ( & output. stdout ) ;
205- let mut killed_any = false ;
206205
206+ // Collect target PIDs (excluding self)
207+ let mut target_pids: Vec < u32 > = Vec :: new ( ) ;
207208 for ( i, line) in stdout. lines ( ) . enumerate ( ) {
208209 if i == 0 { continue ; } // skip header
209210 let trimmed = line. trim ( ) ;
210211 if trimmed. is_empty ( ) { continue ; }
211212 // CSV fields quoted, expect: "Image Name","PID","Session Name","Session#","Mem Usage"
212- // We'll split commas and trim surrounding quotes.
213213 let parts: Vec < String > = trimmed. split ( ',' )
214214 . map ( |s| s. trim ( ) . trim_matches ( '"' ) . to_string ( ) )
215215 . collect ( ) ;
216216 if parts. len ( ) < 2 { continue ; }
217- let pid_str = & parts[ 1 ] ;
218- if let Ok ( pid) = pid_str. parse :: < u32 > ( ) {
219- if pid == this_pid {
220- continue ; // skip self
217+ if let Ok ( pid) = parts[ 1 ] . parse :: < u32 > ( ) {
218+ if pid != this_pid { target_pids. push ( pid) ; }
219+ }
220+ }
221+
222+ if target_pids. is_empty ( ) {
223+ return Ok ( ( ) ) ;
224+ }
225+
226+ // First, try a graceful termination using taskkill without /F (no console tricks)
227+ for pid in & target_pids {
228+ let res = Command :: new ( "taskkill" )
229+ . args ( [ "/PID" , & pid. to_string ( ) ] )
230+ . output ( ) ;
231+ match res {
232+ Ok ( out) => {
233+ if out. status . success ( ) {
234+ info ! ( "Requested graceful termination for PID {} ({})" , pid, image_name) ;
235+ } else {
236+ let stderr = String :: from_utf8_lossy ( & out. stderr ) ;
237+ warn ! ( "Graceful taskkill failed for PID {}: {}" , pid, stderr) ;
238+ }
221239 }
222- // Attempt to kill this PID
240+ Err ( e) => warn ! ( "taskkill (graceful) failed for PID {}: {}" , pid, e) ,
241+ }
242+ }
243+
244+ // Wait 2.5 seconds to allow graceful shutdown
245+ thread:: sleep ( Duration :: from_millis ( 2500 ) ) ;
246+
247+ // Force-kill any remaining instances
248+ let output2 = Command :: new ( "tasklist" )
249+ . args ( [ "/FI" , & format ! ( "IMAGENAME eq {}" , image_name) , "/FO" , "CSV" ] )
250+ . output ( ) ?;
251+
252+ if !output2. status . success ( ) {
253+ let stderr = String :: from_utf8_lossy ( & output2. stderr ) ;
254+ warn ! ( "tasklist failed while verifying remaining instances: {}" , stderr) ;
255+ return Ok ( ( ) ) ;
256+ }
257+
258+ let stdout2 = String :: from_utf8_lossy ( & output2. stdout ) ;
259+ let mut killed_any = false ;
260+
261+ for ( i, line) in stdout2. lines ( ) . enumerate ( ) {
262+ if i == 0 { continue ; }
263+ let trimmed = line. trim ( ) ;
264+ if trimmed. is_empty ( ) { continue ; }
265+ let parts: Vec < String > = trimmed
266+ . split ( ',' )
267+ . map ( |s| s. trim ( ) . trim_matches ( '"' ) . to_string ( ) )
268+ . collect ( ) ;
269+ if parts. len ( ) < 2 { continue ; }
270+ if let Ok ( pid) = parts[ 1 ] . parse :: < u32 > ( ) {
271+ if pid == this_pid { continue ; }
272+ if !target_pids. contains ( & pid) { continue ; } // only those we targeted
273+
223274 let kill = Command :: new ( "taskkill" ) . args ( [ "/PID" , & pid. to_string ( ) , "/F" ] ) . output ( ) ;
224275 match kill {
225276 Ok ( res) => {
226277 if res. status . success ( ) {
227- info ! ( "Terminated process PID {} ({})" , pid, image_name) ;
278+ info ! ( "Force terminated process PID {} ({})" , pid, image_name) ;
228279 killed_any = true ;
229280 } else {
230281 let stderr = String :: from_utf8_lossy ( & res. stderr ) ;
231- // If the process exited between list and kill, ignore the error.
232- warn ! ( "Failed to terminate PID {}: {}" , pid, stderr) ;
282+ warn ! ( "Failed to force terminate PID {}: {}" , pid, stderr) ;
233283 }
234284 }
235285 Err ( e) => warn ! ( "taskkill failed for PID {}: {}" , pid, e) ,
0 commit comments