feat(plugins): add managed runtime SDK and release 2.4.5

This commit is contained in:
chenmingxuan committed 2026-10-30 14:39:21 +08:00
1 parent 506e3bf1c5
commit 2a3bbaa3fb
45 files changed
+3348 -98

No files matched your search

+39 -2
View File
@@ -4,8 +4,8 @@ import ctypes
from ctypes import wintypes
class CaptureProcessJob:
"""A non-inheritable job handle: Windows kills captures when its owner exits."""
class ProcessJob:
"""A non-inheritable job handle that owns a Windows process tree."""
def __init__(self):
class BasicLimits(ctypes.Structure):
@@ -54,6 +54,12 @@ class CaptureProcessJob:
),
("OpenProcess", [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD], wintypes.HANDLE),
("AssignProcessToJobObject", [wintypes.HANDLE, wintypes.HANDLE], wintypes.BOOL),
("TerminateJobObject", [wintypes.HANDLE, wintypes.UINT], wintypes.BOOL),
(
"QueryInformationJobObject",
[wintypes.HANDLE, ctypes.c_int, wintypes.LPVOID, wintypes.DWORD, wintypes.LPVOID],
wintypes.BOOL,
),
("CloseHandle", [wintypes.HANDLE], wintypes.BOOL),
):
function = getattr(self._api, name)
@@ -84,3 +90,34 @@ class CaptureProcessJob:
if self._handle:
self._api.CloseHandle(self._handle)
self._handle = None
def terminate(self):
if self._handle and not self._api.TerminateJobObject(self._handle, 1):
raise ctypes.WinError(ctypes.get_last_error())
def active_processes(self) -> int:
if not self._handle:
return 0
class Accounting(ctypes.Structure):
_fields_ = [
("user_time", ctypes.c_int64),
("kernel_time", ctypes.c_int64),
("period_user_time", ctypes.c_int64),
("period_kernel_time", ctypes.c_int64),
("page_faults", wintypes.DWORD),
("total", wintypes.DWORD),
("active", wintypes.DWORD),
("terminated", wintypes.DWORD),
]
accounting = Accounting()
if not self._api.QueryInformationJobObject(
self._handle, 1, ctypes.byref(accounting), ctypes.sizeof(accounting), None
):
raise ctypes.WinError(ctypes.get_last_error())
return accounting.active
# Keep the recording implementation and its callers on the same ownership primitive.
CaptureProcessJob = ProcessJob