Merge pull request #955 from EightDoor/fix/windows-process-enumeration

fix(ui): enumerate codebase-memory-mcp processes on Windows
This commit is contained in:
Martin Vogel
2026-08-20 15:31:08 +02:00
committed by GitHub
+76 -2
View File
@@ -54,6 +54,7 @@
#include <windows.h>
#include <process.h>
#include <psapi.h> /* GetProcessMemoryInfo */
#include <tlhelp32.h> /* CreateToolhelp32Snapshot, Process32First/Next */
#else
#include <sys/stat.h>
#include <unistd.h>
@@ -560,7 +561,7 @@ static void handle_processes(cbm_http_conn_t *c) {
int pos = 0;
#ifdef _WIN32
/* Windows: GetProcessMemoryInfo + GetProcessTimes */
/* Windows: GetProcessMemoryInfo + GetProcessTimes for the current process */
PROCESS_MEMORY_COUNTERS pmc;
FILETIME ft_create, ft_exit, ft_kernel, ft_user;
double user_s = 0, sys_s = 0;
@@ -578,8 +579,81 @@ static void handle_processes(cbm_http_conn_t *c) {
}
http_appendf(buf, sizeof(buf), &pos,
"{\"self_pid\":%d,\"self_rss_mb\":%.1f,"
"\"self_user_cpu_s\":%.1f,\"self_sys_cpu_s\":%.1f,\"processes\":[]}",
"\"self_user_cpu_s\":%.1f,\"self_sys_cpu_s\":%.1f,\"processes\":[",
(int)_getpid(), (double)rss_bytes / (1024.0 * 1024.0), user_s, sys_s);
/* Enumerate all codebase-memory-mcp.exe processes via toolhelp snapshot */
int proc_count = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE) {
PROCESSENTRY32 pe;
pe.dwSize = sizeof(pe);
for (BOOL ok = Process32First(hSnap, &pe); ok; ok = Process32Next(hSnap, &pe)) {
if (_stricmp(pe.szExeFile, "codebase-memory-mcp.exe") == 0) {
HANDLE hProc = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pe.th32ProcessID);
if (hProc) {
PROCESS_MEMORY_COUNTERS ppmc;
FILETIME ftc, fte, ftk, ftu;
double cpu_user = 0, cpu_sys = 0;
size_t proc_rss = 0;
DWORD elapsed_sec = 0;
if (GetProcessMemoryInfo(hProc, &ppmc, sizeof(ppmc)))
proc_rss = ppmc.WorkingSetSize;
if (GetProcessTimes(hProc, &ftc, &fte, &ftk, &ftu)) {
ULARGE_INTEGER pu, pk;
pu.LowPart = ftu.dwLowDateTime;
pu.HighPart = ftu.dwHighDateTime;
pk.LowPart = ftk.dwLowDateTime;
pk.HighPart = ftk.dwHighDateTime;
cpu_user = (double)pu.QuadPart / 1e7;
cpu_sys = (double)pk.QuadPart / 1e7;
/* 进程创建以来的运行时间 */
FILETIME now_ft;
GetSystemTimeAsFileTime(&now_ft);
ULARGE_INTEGER now_uli, start_uli;
now_uli.LowPart = now_ft.dwLowDateTime;
now_uli.HighPart = now_ft.dwHighDateTime;
start_uli.LowPart = ftc.dwLowDateTime;
start_uli.HighPart = ftc.dwHighDateTime;
/* 时钟偏移保护:防止创建时间微偏未来导致 unsigned 下溢 */
if (now_uli.QuadPart > start_uli.QuadPart) {
ULONGLONG elapsed_100ns = now_uli.QuadPart - start_uli.QuadPart;
elapsed_sec = (DWORD)(elapsed_100ns / 10000000ULL);
}
}
if (proc_count > 0)
buf[pos++] = ',';
http_appendf(buf, sizeof(buf), &pos,
"{\"pid\":%lu,\"cpu\":%.1f,\"rss_mb\":%.1f,"
"\"elapsed\":\"%lu-%02lu:%02lu:%02lu\","
"\"command\":\"codebase-memory-mcp\","
"\"is_self\":%s}",
pe.th32ProcessID, cpu_user + cpu_sys,
(double)proc_rss / (1024.0 * 1024.0),
elapsed_sec / 86400,
(elapsed_sec % 86400) / 3600,
(elapsed_sec % 3600) / 60,
elapsed_sec % 60,
pe.th32ProcessID == (DWORD)_getpid()
? "true" : "false");
if (pos >= (int)sizeof(buf)) {
pos = (int)sizeof(buf) - 1;
}
proc_count++;
CloseHandle(hProc);
}
}
}
CloseHandle(hSnap);
}
http_appendf(buf, sizeof(buf), &pos, "]}");
#else
struct rusage ru;
getrusage(RUSAGE_SELF, &ru);