| 183 | _TP = None # type: Any |
| 184 | |
| 185 | def kill(pid): |
| 186 | # type: (int) -> None |
| 187 | |
| 188 | import ctypes |
| 189 | from ctypes.wintypes import BOOL, DWORD, HANDLE, UINT |
| 190 | |
| 191 | global _OP |
| 192 | if _OP is None: |
| 193 | # https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-openprocess |
| 194 | op = ctypes.windll.kernel32.OpenProcess # type: ignore[attr-defined] |
| 195 | op.argtypes = ( |
| 196 | DWORD, # dwDesiredAccess |
| 197 | BOOL, # bInheritHandle |
| 198 | DWORD, # dwProcessId |
| 199 | ) |
| 200 | op.restype = HANDLE |
| 201 | _OP = op |
| 202 | |
| 203 | phandle = _OP(_PROCESS_TERMINATE, False, pid) |
| 204 | if not phandle: |
| 205 | # TODO(John Sirois): Review literature / experiment and don't raise if this just means |
| 206 | # the process is already dead. |
| 207 | # See: https://github.com/pex-tool/pex/issues/2670 |
| 208 | raise ctypes.WinError() # type: ignore[attr-defined] |
| 209 | |
| 210 | global _TP |
| 211 | if _TP is None: |
| 212 | # https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-terminateprocess |
| 213 | tp = ctypes.windll.kernel32.OpenProcess # type: ignore[attr-defined] |
| 214 | tp.argtypes = ( |
| 215 | HANDLE, # hProcess |
| 216 | UINT, # uExitCode |
| 217 | ) |
| 218 | tp.restype = BOOL |
| 219 | _TP = tp |
| 220 | |
| 221 | if not _TP(phandle, 1): |
| 222 | # TODO(John Sirois): Review literature / experiment and don't raise if this just means |
| 223 | # the process is already dead (may need to consult GetLastError). |
| 224 | # See: https://github.com/pex-tool/pex/issues/2670 |
| 225 | raise ctypes.WinError() # type: ignore[attr-defined] |
| 226 | |
| 227 | else: |
| 228 | |