| 89 | |
| 90 | |
| 91 | def kill_process_interactive(pid: int) -> bool: |
| 92 | system_platform = platform.system() |
| 93 | success = False |
| 94 | logger.info(f"Attempting to terminate process PID: {pid}...") |
| 95 | try: |
| 96 | if system_platform == "Linux" or system_platform == "Darwin": |
| 97 | result_term = subprocess.run( |
| 98 | f"kill {pid}", |
| 99 | shell=True, |
| 100 | capture_output=True, |
| 101 | text=True, |
| 102 | timeout=3, |
| 103 | check=False, |
| 104 | ) |
| 105 | if result_term.returncode == 0: |
| 106 | logger.info(f"SIGTERM signal sent to PID {pid}.") |
| 107 | success = True |
| 108 | else: |
| 109 | logger.warning( |
| 110 | f" PID {pid} SIGTERM failed: {result_term.stderr.strip() or result_term.stdout.strip()}. Trying SIGKILL..." |
| 111 | ) |
| 112 | result_kill = subprocess.run( |
| 113 | f"kill -9 {pid}", |
| 114 | shell=True, |
| 115 | capture_output=True, |
| 116 | text=True, |
| 117 | timeout=3, |
| 118 | check=False, |
| 119 | ) |
| 120 | if result_kill.returncode == 0: |
| 121 | logger.info(f"SIGKILL signal sent to PID {pid}.") |
| 122 | success = True |
| 123 | else: |
| 124 | logger.error( |
| 125 | f" ✗ PID {pid} SIGKILL failed: {result_kill.stderr.strip() or result_kill.stdout.strip()}." |
| 126 | ) |
| 127 | elif system_platform == "Windows": |
| 128 | command_desc = f"taskkill /PID {pid} /T /F" |
| 129 | result = subprocess.run( |
| 130 | command_desc, |
| 131 | shell=True, |
| 132 | capture_output=True, |
| 133 | text=True, |
| 134 | timeout=5, |
| 135 | check=False, |
| 136 | ) |
| 137 | output = result.stdout.strip() |
| 138 | error_output = result.stderr.strip() |
| 139 | if result.returncode == 0 and ( |
| 140 | "SUCCESS" in output.upper() or "成功" in output |
| 141 | ): |
| 142 | logger.info(f"PID {pid} terminated via taskkill /F.") |
| 143 | success = True |
| 144 | elif ( |
| 145 | "could not find process" in error_output.lower() |
| 146 | or "找不到" in error_output |
| 147 | ): # Process may have already exited |
| 148 | logger.info( |