From e8d6b7f9d538b60cbb74f53f89f24051924a4551 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 11:58:12 +0800 Subject: [PATCH 01/16] Add files via upload --- ForegroundBooster.cpp | 145 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 8f00cae..3bb8daa 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -16,6 +16,10 @@ #include #include #include +#include +#include + +std::set> idealCoreCache; #pragma comment(lib, "dwmapi.lib") #pragma comment(lib, "ntdll.lib") @@ -56,6 +60,7 @@ struct Settings int scheduling = -1; int weight = -1; int processListInterval = 60; + int idealCore = -1; }; Settings settings; std::set blackList, whiteList, blackListJob; @@ -204,6 +209,7 @@ void ParseIniFile(const std::wstring& path) else if (key == L"Scheduling") settings.scheduling = std::stoi(value); else if (key == L"Weight") settings.weight = std::stoi(value); else if (key == L"ProcessList") settings.processListInterval = std::stoi(value); + else if (key == L"IdealCore") settings.idealCore = std::stoi(value); } } else if (currentSection == L"BlackList") @@ -387,6 +393,55 @@ void ScanAndResetIoPriorities() LogColor(COLOR_INFO, "[后台扫描] 扫描完成 当前缓存 %zu 个进程\n", processCache.size()); } +// --- 新增函数: 获取进程的主线程ID --- +// 通过遍历线程并比较创建时间来找到第一个创建的线程 +DWORD GetProcessMainThreadId(DWORD dwProcessId) +{ + struct ThreadInfo { + DWORD threadId; + FILETIME creationTime; + }; + + std::vector threads; + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) { + return 0; + } + + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + if (Thread32First(hSnapshot, &te32)) { + do { + if (te32.th32OwnerProcessID == dwProcessId) { + HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID); + if (hThread) { + ThreadInfo info; + info.threadId = te32.th32ThreadID; + FILETIME exitTime, kernelTime, userTime; + if (GetThreadTimes(hThread, &info.creationTime, &exitTime, &kernelTime, &userTime)) { + threads.push_back(info); + } + CloseHandle(hThread); + } + } + } while (Thread32Next(hSnapshot, &te32)); + } + + CloseHandle(hSnapshot); + + if (threads.empty()) { + return 0; + } + + // 根据创建时间排序,找到最早创建的线程 + std::sort(threads.begin(), threads.end(), [](const ThreadInfo& a, const ThreadInfo& b) { + return CompareFileTime(&a.creationTime, &b.creationTime) < 0; + }); + + return threads[0].threadId; +} + void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { if (event != EVENT_SYSTEM_FOREGROUND || !hwnd) @@ -468,6 +523,96 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND LogColor(COLOR_WARNING, " -> 进程位于作业对象黑名单中 跳过Job Object操作\n"); } } + // --- 新增: 设置主线程理想核心的逻辑 --- + if (settings.idealCore >= 0) + { + LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); + std::pair cacheKey = { processNameLower, currentProcessId }; + + if (idealCoreCache.count(cacheKey)) + { + LogColor(COLOR_SUCCESS, " - 跳过: 进程已在缓存中,之前已设置成功。\n"); + } + else + { + bool isCoreAllowed = false; + + // 1. 检查进程亲和性 (Process Affinity) + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) + { + if ((processAffinityMask & (1ULL << settings.idealCore))) + { + isCoreAllowed = true; + LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程亲和性掩码 (0x%llX) 范围内。\n", settings.idealCore, processAffinityMask); + } + } + + // 2. 如果亲和性未设置或不匹配,检查 CPU Sets (适用于较新的Windows版本) + if (!isCoreAllowed) + { + // 动态加载 GetProcessDefaultCpuSets 以兼容旧版系统 + using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); + GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + + if (pGetProcessDefaultCpuSets) + { + ULONG requiredSize = 0; + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + if (requiredSize > 0) + { + std::vector cpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetProcessDefaultCpuSets(hNewProcess, cpuSetIds.data(), (ULONG)cpuSetIds.size() * sizeof(ULONG), &requiredSize)) + { + for (ULONG coreId : cpuSetIds) + { + if (coreId == (ULONG)settings.idealCore) + { + isCoreAllowed = true; + LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); + break; + } + } + } + } + } + } + + if (isCoreAllowed) + { + DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); + if (mainThreadId != 0) + { + HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); + if (hMainThread) + { + if (SetThreadIdealProcessor(hMainThread, settings.idealCore) != (DWORD)-1) + { + LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 %d。\n", mainThreadId, settings.idealCore); + idealCoreCache.insert(cacheKey); // 添加到缓存 + } + else + { + LogColor(COLOR_ERROR, " - 失败: 设置主线程 %lu 的理想核心时出错。错误码: %lu\n", mainThreadId, GetLastError()); + } + CloseHandle(hMainThread); + } + else + { + LogColor(COLOR_ERROR, " - 失败: 无法打开主线程 %lu 的句柄。错误码: %lu\n", mainThreadId, GetLastError()); + } + } + else + { + LogColor(COLOR_ERROR, " - 失败: 无法找到进程的主线程。\n"); + } + } + else + { + LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在进程的亲和性或CPU Sets允许范围内。\n", settings.idealCore); + } + } + } CloseHandle(hNewProcess); } else From 4f7712e40836cb25d38e03c90371b946c7bd69b2 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 12:01:17 +0800 Subject: [PATCH 02/16] Add files via upload --- ForegroundBooster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 3bb8daa..d64814f 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -553,7 +553,7 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND { // 动态加载 GetProcessDefaultCpuSets 以兼容旧版系统 using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); if (pGetProcessDefaultCpuSets) { From a6fd059a50336a10c52f32eebdeaf9d12b1a77de Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:50:36 +0800 Subject: [PATCH 03/16] Add files via upload --- ForegroundBooster.cpp | 66 +++++++++++++++++++++++-------------------- 1 file changed, 35 insertions(+), 31 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index d64814f..bf4a97c 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -527,7 +527,7 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (settings.idealCore >= 0) { LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); - std::pair cacheKey = { processNameLower, currentProcessId }; + std::pair cacheKey = { processNameLower, currentProcessId }; if (idealCoreCache.count(cacheKey)) { @@ -536,48 +536,52 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND else { bool isCoreAllowed = false; - - // 1. 检查进程亲和性 (Process Affinity) - DWORD_PTR processAffinityMask, systemAffinityMask; - if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) - { - if ((processAffinityMask & (1ULL << settings.idealCore))) - { - isCoreAllowed = true; - LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程亲和性掩码 (0x%llX) 范围内。\n", settings.idealCore, processAffinityMask); - } - } + bool isCpuSetRestricted = false; // 标记进程是否受CPU Sets的明确限制 - // 2. 如果亲和性未设置或不匹配,检查 CPU Sets (适用于较新的Windows版本) - if (!isCoreAllowed) - { - // 动态加载 GetProcessDefaultCpuSets 以兼容旧版系统 - using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + // 1. 优先检查 CPU Sets (更现代、更精确的机制) + using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); + GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); - if (pGetProcessDefaultCpuSets) + if (pGetProcessDefaultCpuSets) + { + ULONG requiredSize = 0; + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + if (requiredSize > 0) { - ULONG requiredSize = 0; - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - if (requiredSize > 0) + isCpuSetRestricted = true; // 找到了明确的CPU Sets,这将是唯一依据 + LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将基于此列表进行检查。\n"); + std::vector cpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetProcessDefaultCpuSets(hNewProcess, cpuSetIds.data(), (ULONG)cpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - std::vector cpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, cpuSetIds.data(), (ULONG)cpuSetIds.size() * sizeof(ULONG), &requiredSize)) + for (ULONG coreId : cpuSetIds) { - for (ULONG coreId : cpuSetIds) + if (coreId == (ULONG)settings.idealCore) { - if (coreId == (ULONG)settings.idealCore) - { - isCoreAllowed = true; - LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); - break; - } + isCoreAllowed = true; + LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); + break; } } } } } + // 2. 如果进程不受 CPU Sets 限制,则回退到检查传统的亲和性掩码 + if (!isCpuSetRestricted) + { + LogColor(COLOR_INFO, " - Info: 进程未受 CPU Sets 限制。将检查进程亲和性掩码。\n"); + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) + { + if ((processAffinityMask & (1ULL << settings.idealCore))) + { + isCoreAllowed = true; + LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程亲和性掩码 (0x%llX) 范围内。\n", settings.idealCore, processAffinityMask); + } + } + } + + // 3. 根据最终检查结果执行操作 if (isCoreAllowed) { DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); From 84bc3314ee9fbc3b48c914e67fa18a07398f377f Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 15:53:59 +0800 Subject: [PATCH 04/16] Add files via upload --- ForegroundBooster.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index bf4a97c..3855192 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -527,7 +527,7 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (settings.idealCore >= 0) { LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); - std::pair cacheKey = { processNameLower, currentProcessId }; + std::pair cacheKey = { processNameLower, currentProcessId }; if (idealCoreCache.count(cacheKey)) { From 0c6c66a47bf38cac642d89224368a3334a913d3a Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:02:10 +0800 Subject: [PATCH 05/16] Add files via upload --- ForegroundBooster.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 3855192..aa7034f 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -536,9 +536,8 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND else { bool isCoreAllowed = false; - bool isCpuSetRestricted = false; // 标记进程是否受CPU Sets的明确限制 + bool isCpuSetRestricted = false; - // 1. 优先检查 CPU Sets (更现代、更精确的机制) using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); @@ -548,14 +547,19 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); if (requiredSize > 0) { - isCpuSetRestricted = true; // 找到了明确的CPU Sets,这将是唯一依据 + isCpuSetRestricted = true; LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将基于此列表进行检查。\n"); - std::vector cpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, cpuSetIds.data(), (ULONG)cpuSetIds.size() * sizeof(ULONG), &requiredSize)) + + // --- 修改 1: 使用正确的结构体类型 --- + std::vector cpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); + + // --- 修改 2: 将 vector 的指针传递给 API --- + if (pGetProcessDefaultCpuSets(hNewProcess, (PULONG)cpuSets.data(), (ULONG)cpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize)) { - for (ULONG coreId : cpuSetIds) + // --- 修改 3: 迭代结构体并检查 .Id 成员 --- + for (const auto& cpuSetInfo : cpuSets) { - if (coreId == (ULONG)settings.idealCore) + if (cpuSetInfo.Id == (ULONG)settings.idealCore) { isCoreAllowed = true; LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); @@ -566,7 +570,6 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND } } - // 2. 如果进程不受 CPU Sets 限制,则回退到检查传统的亲和性掩码 if (!isCpuSetRestricted) { LogColor(COLOR_INFO, " - Info: 进程未受 CPU Sets 限制。将检查进程亲和性掩码。\n"); @@ -581,7 +584,6 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND } } - // 3. 根据最终检查结果执行操作 if (isCoreAllowed) { DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); @@ -593,7 +595,7 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (SetThreadIdealProcessor(hMainThread, settings.idealCore) != (DWORD)-1) { LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 %d。\n", mainThreadId, settings.idealCore); - idealCoreCache.insert(cacheKey); // 添加到缓存 + idealCoreCache.insert(cacheKey); } else { From f93a1984cfd62f1af3556c33cf5cb3c55a99b587 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:04:27 +0800 Subject: [PATCH 06/16] Add files via upload --- ForegroundBooster.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index aa7034f..1223fc1 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -550,16 +550,14 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND isCpuSetRestricted = true; LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将基于此列表进行检查。\n"); - // --- 修改 1: 使用正确的结构体类型 --- std::vector cpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); - // --- 修改 2: 将 vector 的指针传递给 API --- if (pGetProcessDefaultCpuSets(hNewProcess, (PULONG)cpuSets.data(), (ULONG)cpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize)) { - // --- 修改 3: 迭代结构体并检查 .Id 成员 --- for (const auto& cpuSetInfo : cpuSets) { - if (cpuSetInfo.Id == (ULONG)settings.idealCore) + // --- 修改点: 使用正确的成员访问方式 cpuSetInfo.CpuSet.Id --- + if (cpuSetInfo.CpuSet.Id == (ULONG)settings.idealCore) { isCoreAllowed = true; LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); From f9d98bd70dec577ba4df1f4bfcc3d0fb1dce0565 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:11:07 +0800 Subject: [PATCH 07/16] Add files via upload --- ForegroundBooster.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 1223fc1..28a78af 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -545,19 +545,31 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND { ULONG requiredSize = 0; pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + if (requiredSize > 0) { isCpuSetRestricted = true; LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将基于此列表进行检查。\n"); - std::vector cpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); + // 正确的类型是 ULONG 向量 + std::vector cpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, (PULONG)cpuSets.data(), (ULONG)cpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize)) + if (pGetProcessDefaultCpuSets(hNewProcess, cpuSetIds.data(), (ULONG)cpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - for (const auto& cpuSetInfo : cpuSets) + // --- 新增的诊断日志 --- + std::wstring id_list_str = L""; + for (size_t i = 0; i < cpuSetIds.size(); ++i) { + id_list_str += std::to_wstring(cpuSetIds[i]); + if (i < cpuSetIds.size() - 1) { + id_list_str += L", "; + } + } + LogColor(COLOR_WARNING, " - 诊断: API返回的CPU Set ID列表: [%ws]\n", id_list_str.c_str()); + // --- 诊断日志结束 --- + + for (ULONG coreId : cpuSetIds) { - // --- 修改点: 使用正确的成员访问方式 cpuSetInfo.CpuSet.Id --- - if (cpuSetInfo.CpuSet.Id == (ULONG)settings.idealCore) + if (coreId == (ULONG)settings.idealCore) { isCoreAllowed = true; LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); From f6b2e1a2267080ca1ee410ce3c79937850db4cda Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:16:53 +0800 Subject: [PATCH 08/16] Add files via upload --- ForegroundBooster.cpp | 50 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 28a78af..032785a 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -539,9 +539,12 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND bool isCpuSetRestricted = false; using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - GetProcessDefaultCpuSetsPtr pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); - if (pGetProcessDefaultCpuSets) + auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); + + if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation) { ULONG requiredSize = 0; pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); @@ -549,31 +552,34 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (requiredSize > 0) { isCpuSetRestricted = true; - LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将基于此列表进行检查。\n"); + LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将执行ID到逻辑核心的转换检查。\n"); + + std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); + pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize); - // 正确的类型是 ULONG 向量 - std::vector cpuSetIds(requiredSize / sizeof(ULONG)); + // 为了快速查找,将进程的ID放入一个set中 + std::set allowedIds(processCpuSetIds.begin(), processCpuSetIds.end()); - if (pGetProcessDefaultCpuSets(hNewProcess, cpuSetIds.data(), (ULONG)cpuSetIds.size() * sizeof(ULONG), &requiredSize)) + // 现在获取系统所有的CPU Set信息来进行“翻译” + pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); + if (requiredSize > 0) { - // --- 新增的诊断日志 --- - std::wstring id_list_str = L""; - for (size_t i = 0; i < cpuSetIds.size(); ++i) { - id_list_str += std::to_wstring(cpuSetIds[i]); - if (i < cpuSetIds.size() - 1) { - id_list_str += L", "; - } - } - LogColor(COLOR_WARNING, " - 诊断: API返回的CPU Set ID列表: [%ws]\n", id_list_str.c_str()); - // --- 诊断日志结束 --- - - for (ULONG coreId : cpuSetIds) + std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); + if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) { - if (coreId == (ULONG)settings.idealCore) + for (const auto& setInfo : systemCpuSets) { - isCoreAllowed = true; - LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程的 CPU Sets 列表中。\n", settings.idealCore); - break; + // 检查这个系统核心的ID是否在进程允许的ID列表中 + if (allowedIds.count(setInfo.CpuSet.Id)) + { + // 如果是,再检查这个核心的逻辑编号是否是我们想要的 + if (setInfo.CpuSet.LogicalProcessorIndex == (BYTE)settings.idealCore) + { + isCoreAllowed = true; + LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d (对应ID %lu) 在进程允许的CPU Sets中。\n", settings.idealCore, setInfo.CpuSet.Id); + break; + } + } } } } From dee5bd2661318330b6ecc5716009126f6889c44e Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:22:44 +0800 Subject: [PATCH 09/16] Add files via upload --- ForegroundBooster.cpp | 156 ++++++++++++++++++++++-------------------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 032785a..0fd3acf 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -536,101 +536,109 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND else { bool isCoreAllowed = false; - bool isCpuSetRestricted = false; - + using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); + using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); + auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); - if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation) + if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx) { + // Step 1: Get the full system CPU map to perform translations ULONG requiredSize = 0; - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - + pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); if (requiredSize > 0) { - isCpuSetRestricted = true; - LogColor(COLOR_INFO, " - Info: 进程受 CPU Sets 限制。将执行ID到逻辑核心的转换检查。\n"); - - std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); - pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize); - - // 为了快速查找,将进程的ID放入一个set中 - std::set allowedIds(processCpuSetIds.begin(), processCpuSetIds.end()); - - // 现在获取系统所有的CPU Set信息来进行“翻译” - pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); - if (requiredSize > 0) + std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); + if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) { - std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); - if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) - { - for (const auto& setInfo : systemCpuSets) - { - // 检查这个系统核心的ID是否在进程允许的ID列表中 - if (allowedIds.count(setInfo.CpuSet.Id)) - { - // 如果是,再检查这个核心的逻辑编号是否是我们想要的 - if (setInfo.CpuSet.LogicalProcessorIndex == (BYTE)settings.idealCore) - { + // Step 2: Translate the flat IdealCore index into a PROCESSOR_NUMBER and a CPU Set ID + ULONG targetCpuSetId = ULONG_MAX; + PROCESSOR_NUMBER targetProcessorNumber = {}; + bool targetFound = false; + + // We need to know group boundaries to calculate the flat index correctly + std::map groupProcessorCount; + for (const auto& setInfo : systemCpuSets) { + if (setInfo.Type == CpuSetInformation) { + groupProcessorCount[setInfo.CpuSet.Group]++; + } + } + + int currentFlatIndex = 0; + for (WORD groupIndex = 0; groupIndex < groupProcessorCount.size(); ++groupIndex) { + for (BYTE processorIndex = 0; processorIndex < groupProcessorCount[groupIndex]; ++processorIndex) { + if (currentFlatIndex == settings.idealCore) { + targetProcessorNumber.Group = groupIndex; + targetProcessorNumber.Number = processorIndex; + targetFound = true; + break; + } + currentFlatIndex++; + } + if (targetFound) break; + } + + if (targetFound) { + LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); + // Now find the CPU Set ID for this specific PROCESSOR_NUMBER + for (const auto& setInfo : systemCpuSets) { + if (setInfo.Type == CpuSetInformation && setInfo.CpuSet.Group == targetProcessorNumber.Group && setInfo.CpuSet.LogicalProcessorIndex == targetProcessorNumber.Number) { + targetCpuSetId = setInfo.CpuSet.Id; + LogColor(COLOR_INFO, " - 诊断: 对应的CPU Set ID为 %lu。\n", targetCpuSetId); + break; + } + } + } + + // Step 3: Check if the target CPU Set ID is allowed for the process + if (targetCpuSetId != ULONG_MAX) { + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + if (requiredSize > 0) { + std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { + for (ULONG allowedId : processCpuSetIds) { + if (allowedId == targetCpuSetId) { + isCoreAllowed = true; + break; + } + } + } + } else { // No specific CPU sets, check affinity + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { + if ((processAffinityMask & (1ULL << settings.idealCore))) { isCoreAllowed = true; - LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d (对应ID %lu) 在进程允许的CPU Sets中。\n", settings.idealCore, setInfo.CpuSet.Id); - break; } } } } - } - } - } - if (!isCpuSetRestricted) - { - LogColor(COLOR_INFO, " - Info: 进程未受 CPU Sets 限制。将检查进程亲和性掩码。\n"); - DWORD_PTR processAffinityMask, systemAffinityMask; - if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) - { - if ((processAffinityMask & (1ULL << settings.idealCore))) - { - isCoreAllowed = true; - LogColor(COLOR_INFO, " - 检查通过: 理想核心 %d 在进程亲和性掩码 (0x%llX) 范围内。\n", settings.idealCore, processAffinityMask); - } - } - } - - if (isCoreAllowed) - { - DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); - if (mainThreadId != 0) - { - HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); - if (hMainThread) - { - if (SetThreadIdealProcessor(hMainThread, settings.idealCore) != (DWORD)-1) - { - LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 %d。\n", mainThreadId, settings.idealCore); - idealCoreCache.insert(cacheKey); - } - else - { - LogColor(COLOR_ERROR, " - 失败: 设置主线程 %lu 的理想核心时出错。错误码: %lu\n", mainThreadId, GetLastError()); + // Step 4: If allowed, set the ideal processor using the modern API + if (isCoreAllowed) { + LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d (ID %lu) 在进程允许的CPU Sets中。\n", settings.idealCore, targetCpuSetId); + DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); + if (mainThreadId != 0) { + HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); + if (hMainThread) { + if (pSetThreadIdealProcessorEx(hMainThread, &targetProcessorNumber, NULL)) { + LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 (组: %d, 索引: %d)。\n", mainThreadId, targetProcessorNumber.Group, targetProcessorNumber.Number); + idealCoreCache.insert(cacheKey); + } else { + LogColor(COLOR_ERROR, " - 失败: SetThreadIdealProcessorEx 调用失败。错误码: %lu\n", GetLastError()); + } + CloseHandle(hMainThread); + } + } } - CloseHandle(hMainThread); - } - else - { - LogColor(COLOR_ERROR, " - 失败: 无法打开主线程 %lu 的句柄。错误码: %lu\n", mainThreadId, GetLastError()); } } - else - { - LogColor(COLOR_ERROR, " - 失败: 无法找到进程的主线程。\n"); - } } - else - { + + if (!isCoreAllowed) { LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在进程的亲和性或CPU Sets允许范围内。\n", settings.idealCore); } } From f30834752b6213ff5555ca9c7c2e68c67470caf1 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:35:19 +0800 Subject: [PATCH 10/16] Add files via upload --- ForegroundBooster.cpp | 170 +++++++++++++++++++++--------------------- 1 file changed, 87 insertions(+), 83 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 0fd3acf..7a013ef 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -525,97 +525,101 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND } // --- 新增: 设置主线程理想核心的逻辑 --- if (settings.idealCore >= 0) - { - LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); - std::pair cacheKey = { processNameLower, currentProcessId }; +{ + LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); + std::pair cacheKey = { processNameLower, currentProcessId }; - if (idealCoreCache.count(cacheKey)) - { - LogColor(COLOR_SUCCESS, " - 跳过: 进程已在缓存中,之前已设置成功。\n"); - } - else - { - bool isCoreAllowed = false; - - using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); - using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); + if (idealCoreCache.count(cacheKey)) + { + LogColor(COLOR_SUCCESS, " - 跳过: 进程已在缓存中,之前已设置成功。\n"); + } + else + { + bool isCoreAllowed = false; + + using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); + using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); + using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); - auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); - auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); - auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); + auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); + auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); - if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx) - { - // Step 1: Get the full system CPU map to perform translations - ULONG requiredSize = 0; - pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); - if (requiredSize > 0) - { - std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); - if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) - { - // Step 2: Translate the flat IdealCore index into a PROCESSOR_NUMBER and a CPU Set ID - ULONG targetCpuSetId = ULONG_MAX; - PROCESSOR_NUMBER targetProcessorNumber = {}; - bool targetFound = false; - - // We need to know group boundaries to calculate the flat index correctly - std::map groupProcessorCount; - for (const auto& setInfo : systemCpuSets) { - if (setInfo.Type == CpuSetInformation) { - groupProcessorCount[setInfo.CpuSet.Group]++; - } - } + if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx) + { + // Step 1: Get the full system CPU map to perform translations + ULONG requiredSize = 0; + pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); + if (requiredSize > 0) + { + std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); + if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) + { + // 【修复开始】 + // Step 2: 翻译扁平化的 IdealCore 索引到 PROCESSOR_NUMBER 和 CPU Set ID (健壮方法) + ULONG targetCpuSetId = ULONG_MAX; + PROCESSOR_NUMBER targetProcessorNumber = {}; + bool targetFound = false; + + // 首先, 筛选出真正的CPU核心信息 + std::vector availableCpuSets; + for (const auto& setInfo : systemCpuSets) { + if (setInfo.Type == CpuSetInformation) { + availableCpuSets.push_back(setInfo); + } + } - int currentFlatIndex = 0; - for (WORD groupIndex = 0; groupIndex < groupProcessorCount.size(); ++groupIndex) { - for (BYTE processorIndex = 0; processorIndex < groupProcessorCount[groupIndex]; ++processorIndex) { - if (currentFlatIndex == settings.idealCore) { - targetProcessorNumber.Group = groupIndex; - targetProcessorNumber.Number = processorIndex; - targetFound = true; - break; - } - currentFlatIndex++; - } - if (targetFound) break; - } - - if (targetFound) { - LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); - // Now find the CPU Set ID for this specific PROCESSOR_NUMBER - for (const auto& setInfo : systemCpuSets) { - if (setInfo.Type == CpuSetInformation && setInfo.CpuSet.Group == targetProcessorNumber.Group && setInfo.CpuSet.LogicalProcessorIndex == targetProcessorNumber.Number) { - targetCpuSetId = setInfo.CpuSet.Id; - LogColor(COLOR_INFO, " - 诊断: 对应的CPU Set ID为 %lu。\n", targetCpuSetId); - break; - } + // 其次, 对列表进行排序以确保可预测的、规范的顺序 + std::sort(availableCpuSets.begin(), availableCpuSets.end(), [](const SYSTEM_CPU_SET_INFORMATION& a, const SYSTEM_CPU_SET_INFORMATION& b) { + if (a.CpuSet.Group != b.CpuSet.Group) { + return a.CpuSet.Group < b.CpuSet.Group; + } + return a.CpuSet.LogicalProcessorIndex < b.CpuSet.LogicalProcessorIndex; + }); + + // 第三, 从排序后的列表中选择第 N 个核心 + if (settings.idealCore >= 0 && settings.idealCore < availableCpuSets.size()) { + const auto& targetSet = availableCpuSets[settings.idealCore]; + targetProcessorNumber.Group = targetSet.CpuSet.Group; + targetProcessorNumber.Number = targetSet.CpuSet.LogicalProcessorIndex; + targetCpuSetId = targetSet.CpuSet.Id; + targetFound = true; + LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); + LogColor(COLOR_INFO, " - 诊断: 对应的CPU Set ID为 %lu。\n", targetCpuSetId); + } + // 【修复结束】 + + // Step 3: Check if the target CPU Set ID is allowed for the process + if (targetFound) { // 使用 targetFound 替代 targetCpuSetId != ULONG_MAX + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + if (requiredSize > 0) { + std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { + for (ULONG allowedId : processCpuSetIds) { + if (allowedId == targetCpuSetId) { + isCoreAllowed = true; + break; } } - - // Step 3: Check if the target CPU Set ID is allowed for the process - if (targetCpuSetId != ULONG_MAX) { - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - if (requiredSize > 0) { - std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - for (ULONG allowedId : processCpuSetIds) { - if (allowedId == targetCpuSetId) { - isCoreAllowed = true; - break; - } - } - } - } else { // No specific CPU sets, check affinity - DWORD_PTR processAffinityMask, systemAffinityMask; - if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { - if ((processAffinityMask & (1ULL << settings.idealCore))) { - isCoreAllowed = true; - } - } + } + } else { // No specific CPU sets, check affinity + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { + // 在检查亲和性时,也应该使用翻译后的 Group 和 Number 来构建掩码,而不是直接用 idealCore + PROCESSOR_NUMBER procNum = {}; + GetCurrentProcessorNumberEx(&procNum); // 获取当前组信息 + if (targetProcessorNumber.Group == procNum.Group) { // 简化处理,仅处理同一组内的亲和性 + if ((processAffinityMask & (1ULL << targetProcessorNumber.Number))) { + isCoreAllowed = true; } + } else { + // 跨组亲和性检查更复杂,但对于大多数现代PC,CPU Sets是首选方法 + // 如果进程没有设置CPU Sets,它通常可以使用所有核心 + isCoreAllowed = true; } + } + } + } // Step 4: If allowed, set the ideal processor using the modern API if (isCoreAllowed) { From 677dec5613fb3e691eeb03f6ab6ea5e1eac68df3 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:43:04 +0800 Subject: [PATCH 11/16] Add files via upload --- ForegroundBooster.cpp | 185 +++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 94 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 7a013ef..88a0e0e 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -525,105 +525,103 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND } // --- 新增: 设置主线程理想核心的逻辑 --- if (settings.idealCore >= 0) -{ - LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); - std::pair cacheKey = { processNameLower, currentProcessId }; - - if (idealCoreCache.count(cacheKey)) - { - LogColor(COLOR_SUCCESS, " - 跳过: 进程已在缓存中,之前已设置成功。\n"); - } - else - { - bool isCoreAllowed = false; - - using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); - using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); - - auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); - auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); - auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); - - if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx) - { - // Step 1: Get the full system CPU map to perform translations - ULONG requiredSize = 0; - pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); - if (requiredSize > 0) { - std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); - if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) + LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); + std::pair cacheKey = { processNameLower, currentProcessId }; + + if (idealCoreCache.count(cacheKey)) { - // 【修复开始】 - // Step 2: 翻译扁平化的 IdealCore 索引到 PROCESSOR_NUMBER 和 CPU Set ID (健壮方法) - ULONG targetCpuSetId = ULONG_MAX; - PROCESSOR_NUMBER targetProcessorNumber = {}; - bool targetFound = false; - - // 首先, 筛选出真正的CPU核心信息 - std::vector availableCpuSets; - for (const auto& setInfo : systemCpuSets) { - if (setInfo.Type == CpuSetInformation) { - availableCpuSets.push_back(setInfo); - } - } + LogColor(COLOR_SUCCESS, " - 跳过: 进程已在缓存中,之前已设置成功。\n"); + } + else + { + bool isCoreAllowed = false; + + using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); + using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); + using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); - // 其次, 对列表进行排序以确保可预测的、规范的顺序 - std::sort(availableCpuSets.begin(), availableCpuSets.end(), [](const SYSTEM_CPU_SET_INFORMATION& a, const SYSTEM_CPU_SET_INFORMATION& b) { - if (a.CpuSet.Group != b.CpuSet.Group) { - return a.CpuSet.Group < b.CpuSet.Group; - } - return a.CpuSet.LogicalProcessorIndex < b.CpuSet.LogicalProcessorIndex; - }); - - // 第三, 从排序后的列表中选择第 N 个核心 - if (settings.idealCore >= 0 && settings.idealCore < availableCpuSets.size()) { - const auto& targetSet = availableCpuSets[settings.idealCore]; - targetProcessorNumber.Group = targetSet.CpuSet.Group; - targetProcessorNumber.Number = targetSet.CpuSet.LogicalProcessorIndex; - targetCpuSetId = targetSet.CpuSet.Id; - targetFound = true; - LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); - LogColor(COLOR_INFO, " - 诊断: 对应的CPU Set ID为 %lu。\n", targetCpuSetId); - } - // 【修复结束】 - - // Step 3: Check if the target CPU Set ID is allowed for the process - if (targetFound) { // 使用 targetFound 替代 targetCpuSetId != ULONG_MAX - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - if (requiredSize > 0) { - std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - for (ULONG allowedId : processCpuSetIds) { - if (allowedId == targetCpuSetId) { - isCoreAllowed = true; - break; + auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); + auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); + auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); + + if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx) + { + ULONG requiredSize = 0; + pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); + if (requiredSize > 0) + { + std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); + if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) + { + // Step 1: 筛选并排序,建立一个从扁平索引到核心信息的稳定映射 + std::vector availableCpuSets; + for (const auto& setInfo : systemCpuSets) { + if (setInfo.Type == CpuSetInformation) { + availableCpuSets.push_back(setInfo); } } - } - } else { // No specific CPU sets, check affinity - DWORD_PTR processAffinityMask, systemAffinityMask; - if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { - // 在检查亲和性时,也应该使用翻译后的 Group 和 Number 来构建掩码,而不是直接用 idealCore - PROCESSOR_NUMBER procNum = {}; - GetCurrentProcessorNumberEx(&procNum); // 获取当前组信息 - if (targetProcessorNumber.Group == procNum.Group) { // 简化处理,仅处理同一组内的亲和性 - if ((processAffinityMask & (1ULL << targetProcessorNumber.Number))) { - isCoreAllowed = true; + std::sort(availableCpuSets.begin(), availableCpuSets.end(), [](const SYSTEM_CPU_SET_INFORMATION& a, const SYSTEM_CPU_SET_INFORMATION& b) { + if (a.CpuSet.Group != b.CpuSet.Group) return a.CpuSet.Group < b.CpuSet.Group; + return a.CpuSet.LogicalProcessorIndex < b.CpuSet.LogicalProcessorIndex; + }); + + // Step 2: 根据排序后的列表,找到目标核心信息 + ULONG targetCpuSetId = ULONG_MAX; + PROCESSOR_NUMBER targetProcessorNumber = {}; + bool targetFound = false; + + if (settings.idealCore >= 0 && settings.idealCore < availableCpuSets.size()) { + const auto& targetSet = availableCpuSets[settings.idealCore]; + targetProcessorNumber.Group = targetSet.CpuSet.Group; + targetProcessorNumber.Number = targetSet.CpuSet.LogicalProcessorIndex; + targetCpuSetId = targetSet.CpuSet.Id; + targetFound = true; + LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); + LogColor(COLOR_INFO, " - 诊断: 对应的CPU Set ID为 %lu。\n", targetCpuSetId); + } + + if (targetFound) + { + // Step 3: 【已修复】检查目标核心是否被进程允许 + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + + // 优先使用 CPU Sets 进行判断 + if (requiredSize > 0) { + std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { + for (ULONG allowedId : processCpuSetIds) { + if (allowedId == targetCpuSetId) { + isCoreAllowed = true; + break; + } + } + } + } + // 如果没有返回 CPU Sets,则回退到检查传统的亲和性掩码 + else { + LogColor(COLOR_INFO, " - 诊断: 进程未设置显式CPU Sets,回退到检查亲和性掩码。\n"); + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { + // 亲和性掩码是针对单个处理器组的。我们需要检查目标核心所在的组是否为主组(通常是0), + // 并且在该组的掩码中对应的位是否为1。 + // 注意:这是一个简化处理,在具有多个活动组的复杂情况下可能不完全准确,但对绝大多数PC有效。 + if (targetProcessorNumber.Group == 0) { + if ((processAffinityMask & (static_cast(1) << targetProcessorNumber.Number))) { + isCoreAllowed = true; + } + } else { + // 对于非主组的核心,如果进程没有设置CPU Sets,通常意味着它可以使用该组的所有核心。 + // 在这种情况下,我们假定为允许。 + isCoreAllowed = true; + } + } } - } else { - // 跨组亲和性检查更复杂,但对于大多数现代PC,CPU Sets是首选方法 - // 如果进程没有设置CPU Sets,它通常可以使用所有核心 - isCoreAllowed = true; } - } - } - } - // Step 4: If allowed, set the ideal processor using the modern API + // Step 4: 如果允许,则设置理想核心 if (isCoreAllowed) { - LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d (ID %lu) 在进程允许的CPU Sets中。\n", settings.idealCore, targetCpuSetId); + LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d 在进程允许的范围内。\n", settings.idealCore); DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); if (mainThreadId != 0) { HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); @@ -638,13 +636,12 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND } } } + else { + LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在进程的亲和性或CPU Sets允许范围内。\n", settings.idealCore); + } } } } - - if (!isCoreAllowed) { - LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在进程的亲和性或CPU Sets允许范围内。\n", settings.idealCore); - } } } CloseHandle(hNewProcess); From 5f586fdc5c0c3971bcc90d05852c6be9cfe0be6a Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 16:54:47 +0800 Subject: [PATCH 12/16] Add files via upload --- ForegroundBooster.cpp | 59 ++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 88a0e0e..4817d63 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -61,6 +61,7 @@ struct Settings int weight = -1; int processListInterval = 60; int idealCore = -1; + bool forceIdealCore = false; }; Settings settings; std::set blackList, whiteList, blackListJob; @@ -210,6 +211,7 @@ void ParseIniFile(const std::wstring& path) else if (key == L"Weight") settings.weight = std::stoi(value); else if (key == L"ProcessList") settings.processListInterval = std::stoi(value); else if (key == L"IdealCore") settings.idealCore = std::stoi(value); + else if (key == L"ForceIdealCore") settings.forceIdealCore = (std::stoi(value) == 1); } } else if (currentSection == L"BlackList") @@ -554,27 +556,20 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) { - // Step 1: 筛选并排序,建立一个从扁平索引到核心信息的稳定映射 std::vector availableCpuSets; - for (const auto& setInfo : systemCpuSets) { - if (setInfo.Type == CpuSetInformation) { - availableCpuSets.push_back(setInfo); - } - } + for (const auto& setInfo : systemCpuSets) { if (setInfo.Type == CpuSetInformation) availableCpuSets.push_back(setInfo); } std::sort(availableCpuSets.begin(), availableCpuSets.end(), [](const SYSTEM_CPU_SET_INFORMATION& a, const SYSTEM_CPU_SET_INFORMATION& b) { if (a.CpuSet.Group != b.CpuSet.Group) return a.CpuSet.Group < b.CpuSet.Group; return a.CpuSet.LogicalProcessorIndex < b.CpuSet.LogicalProcessorIndex; }); - // Step 2: 根据排序后的列表,找到目标核心信息 ULONG targetCpuSetId = ULONG_MAX; PROCESSOR_NUMBER targetProcessorNumber = {}; bool targetFound = false; if (settings.idealCore >= 0 && settings.idealCore < availableCpuSets.size()) { const auto& targetSet = availableCpuSets[settings.idealCore]; - targetProcessorNumber.Group = targetSet.CpuSet.Group; - targetProcessorNumber.Number = targetSet.CpuSet.LogicalProcessorIndex; + targetProcessorNumber = { targetSet.CpuSet.Group, targetSet.CpuSet.LogicalProcessorIndex }; targetCpuSetId = targetSet.CpuSet.Id; targetFound = true; LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); @@ -583,45 +578,36 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (targetFound) { - // Step 3: 【已修复】检查目标核心是否被进程允许 pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - - // 优先使用 CPU Sets 进行判断 if (requiredSize > 0) { std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - for (ULONG allowedId : processCpuSetIds) { - if (allowedId == targetCpuSetId) { - isCoreAllowed = true; - break; - } - } + // --- 诊断代码 --- + LogColor(COLOR_INFO, " - 诊断: 进程允许的CPU Set ID列表为: [ "); + for (size_t i = 0; i < processCpuSetIds.size(); ++i) printf("%lu%s", processCpuSetIds[i], (i == processCpuSetIds.size() - 1) ? "" : ", "); + printf(" ]\n"); + // --- 诊断结束 --- + for (ULONG allowedId : processCpuSetIds) { if (allowedId == targetCpuSetId) { isCoreAllowed = true; break; } } } - } - // 如果没有返回 CPU Sets,则回退到检查传统的亲和性掩码 - else { + } else { LogColor(COLOR_INFO, " - 诊断: 进程未设置显式CPU Sets,回退到检查亲和性掩码。\n"); DWORD_PTR processAffinityMask, systemAffinityMask; if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { - // 亲和性掩码是针对单个处理器组的。我们需要检查目标核心所在的组是否为主组(通常是0), - // 并且在该组的掩码中对应的位是否为1。 - // 注意:这是一个简化处理,在具有多个活动组的复杂情况下可能不完全准确,但对绝大多数PC有效。 - if (targetProcessorNumber.Group == 0) { - if ((processAffinityMask & (static_cast(1) << targetProcessorNumber.Number))) { - isCoreAllowed = true; - } - } else { - // 对于非主组的核心,如果进程没有设置CPU Sets,通常意味着它可以使用该组的所有核心。 - // 在这种情况下,我们假定为允许。 + if (targetProcessorNumber.Group == 0 && (processAffinityMask & (static_cast(1) << targetProcessorNumber.Number))) { isCoreAllowed = true; - } + } else if (targetProcessorNumber.Group > 0) { isCoreAllowed = true; } } } } - // Step 4: 如果允许,则设置理想核心 - if (isCoreAllowed) { - LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d 在进程允许的范围内。\n", settings.idealCore); + // --- 强制覆盖逻辑 --- + if (isCoreAllowed || settings.forceIdealCore) { + if (!isCoreAllowed) { + LogColor(COLOR_WARNING, " - 警告: 检查未通过,但根据配置强制执行 (ForceIdealCore=1)。\n"); + } else { + LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d 在进程允许的范围内。\n", settings.idealCore); + } + DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); if (mainThreadId != 0) { HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); @@ -635,8 +621,7 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND CloseHandle(hMainThread); } } - } - else { + } else { LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在进程的亲和性或CPU Sets允许范围内。\n", settings.idealCore); } } From b79dacf88b480293beb5e692456142aad54e00ad Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:12:07 +0800 Subject: [PATCH 13/16] Add files via upload --- ForegroundBooster.cpp | 84 +++++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 4817d63..14c83a7 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -542,12 +542,16 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); + // 【新API】 + using GetThreadSelectedCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); + // 【新API】 + auto pGetThreadSelectedCpuSets = (GetThreadSelectedCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadSelectedCpuSets"); - if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx) + if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx && pGetThreadSelectedCpuSets) { ULONG requiredSize = 0; pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); @@ -578,51 +582,55 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (targetFound) { - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - if (requiredSize > 0) { - std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - // --- 诊断代码 --- - LogColor(COLOR_INFO, " - 诊断: 进程允许的CPU Set ID列表为: [ "); - for (size_t i = 0; i < processCpuSetIds.size(); ++i) printf("%lu%s", processCpuSetIds[i], (i == processCpuSetIds.size() - 1) ? "" : ", "); - printf(" ]\n"); - // --- 诊断结束 --- - for (ULONG allowedId : processCpuSetIds) { if (allowedId == targetCpuSetId) { isCoreAllowed = true; break; } } - } - } else { - LogColor(COLOR_INFO, " - 诊断: 进程未设置显式CPU Sets,回退到检查亲和性掩码。\n"); - DWORD_PTR processAffinityMask, systemAffinityMask; - if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { - if (targetProcessorNumber.Group == 0 && (processAffinityMask & (static_cast(1) << targetProcessorNumber.Number))) { - isCoreAllowed = true; - } else if (targetProcessorNumber.Group > 0) { isCoreAllowed = true; } - } - } - } - - // --- 强制覆盖逻辑 --- - if (isCoreAllowed || settings.forceIdealCore) { - if (!isCoreAllowed) { - LogColor(COLOR_WARNING, " - 警告: 检查未通过,但根据配置强制执行 (ForceIdealCore=1)。\n"); - } else { - LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d 在进程允许的范围内。\n", settings.idealCore); - } - DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); if (mainThreadId != 0) { - HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); + HANDLE hMainThread = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, FALSE, mainThreadId); if (hMainThread) { - if (pSetThreadIdealProcessorEx(hMainThread, &targetProcessorNumber, NULL)) { - LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 (组: %d, 索引: %d)。\n", mainThreadId, targetProcessorNumber.Group, targetProcessorNumber.Number); - idealCoreCache.insert(cacheKey); + // 【修复核心】: 优先查询线程自身的CPU Sets + pGetThreadSelectedCpuSets(hMainThread, NULL, 0, &requiredSize); + if (requiredSize > 0) { + std::vector threadCpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetThreadSelectedCpuSets(hMainThread, threadCpuSetIds.data(), (ULONG)threadCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { + LogColor(COLOR_INFO, " - 诊断: [线程级] 允许的CPU Set ID列表为: [ "); + for (size_t i = 0; i < threadCpuSetIds.size(); ++i) printf("%lu%s", threadCpuSetIds[i], (i == threadCpuSetIds.size() - 1) ? "" : ", "); + printf(" ]\n"); + for (ULONG allowedId : threadCpuSetIds) { if (allowedId == targetCpuSetId) { isCoreAllowed = true; break; } } + } + } + + // 如果线程没有特定设置,再回退到检查进程的默认设置 + if (!isCoreAllowed) { + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + if (requiredSize > 0) { + std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); + if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { + LogColor(COLOR_INFO, " - 诊断: [进程级] 允许的CPU Set ID列表为: [ "); + for (size_t i = 0; i < processCpuSetIds.size(); ++i) printf("%lu%s", processCpuSetIds[i], (i == processCpuSetIds.size() - 1) ? "" : ", "); + printf(" ]\n"); + for (ULONG allowedId : processCpuSetIds) { if (allowedId == targetCpuSetId) { isCoreAllowed = true; break; } } + } + } + } + + // 最终决策 + if (isCoreAllowed || settings.forceIdealCore) { + if (!isCoreAllowed) { + LogColor(COLOR_WARNING, " - 警告: 检查未通过,但根据配置强制执行 (ForceIdealCore=1)。\n"); + } else { + LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d 在进程允许的范围内。\n", settings.idealCore); + } + if (pSetThreadIdealProcessorEx(hMainThread, &targetProcessorNumber, NULL)) { + LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 (组: %d, 索引: %d)。\n", mainThreadId, targetProcessorNumber.Group, targetProcessorNumber.Number); + idealCoreCache.insert(cacheKey); + } else { + LogColor(COLOR_ERROR, " - 失败: SetThreadIdealProcessorEx 调用失败。错误码: %lu\n", GetLastError()); + } } else { - LogColor(COLOR_ERROR, " - 失败: SetThreadIdealProcessorEx 调用失败。错误码: %lu\n", GetLastError()); + LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在线程或进程的CPU Sets允许范围内。\n", settings.idealCore); } CloseHandle(hMainThread); } } - } else { - LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在进程的亲和性或CPU Sets允许范围内。\n", settings.idealCore); } } } From aca699d2e434ef1f4b3bb4e4157dad65048b4aa6 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:25:04 +0800 Subject: [PATCH 14/16] Add files via upload --- ForegroundBooster.cpp | 155 ++++++++++++++---------------------------- 1 file changed, 52 insertions(+), 103 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 14c83a7..bad252e 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -526,117 +526,66 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND } } // --- 新增: 设置主线程理想核心的逻辑 --- - if (settings.idealCore >= 0) - { - LogColor(COLOR_INFO, " -> [理想核心] 正在检查理想核心设置 (配置为: %d)...\n", settings.idealCore); - std::pair cacheKey = { processNameLower, currentProcessId }; - - if (idealCoreCache.count(cacheKey)) - { - LogColor(COLOR_SUCCESS, " - 跳过: 进程已在缓存中,之前已设置成功。\n"); - } - else - { - bool isCoreAllowed = false; - - using GetProcessDefaultCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - using GetSystemCpuSetInformationPtr = BOOL(WINAPI*)(PSYSTEM_CPU_SET_INFORMATION, ULONG, PULONG, HANDLE, ULONG); - using SetThreadIdealProcessorExPtr = BOOL(WINAPI*)(HANDLE, PPROCESSOR_NUMBER, PPROCESSOR_NUMBER); - // 【新API】 - using GetThreadSelectedCpuSetsPtr = BOOL(WINAPI*)(HANDLE, PULONG, ULONG, PULONG); - - auto pGetProcessDefaultCpuSets = (GetProcessDefaultCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetProcessDefaultCpuSets"); - auto pGetSystemCpuSetInformation = (GetSystemCpuSetInformationPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetSystemCpuSetInformation"); - auto pSetThreadIdealProcessorEx = (SetThreadIdealProcessorExPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetThreadIdealProcessorEx"); - // 【新API】 - auto pGetThreadSelectedCpuSets = (GetThreadSelectedCpuSetsPtr)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetThreadSelectedCpuSets"); - - if (pGetProcessDefaultCpuSets && pGetSystemCpuSetInformation && pSetThreadIdealProcessorEx && pGetThreadSelectedCpuSets) - { - ULONG requiredSize = 0; - pGetSystemCpuSetInformation(NULL, 0, &requiredSize, GetCurrentProcess(), 0); - if (requiredSize > 0) - { - std::vector systemCpuSets(requiredSize / sizeof(SYSTEM_CPU_SET_INFORMATION)); - if (pGetSystemCpuSetInformation(systemCpuSets.data(), (ULONG)systemCpuSets.size() * sizeof(SYSTEM_CPU_SET_INFORMATION), &requiredSize, GetCurrentProcess(), 0)) - { - std::vector availableCpuSets; - for (const auto& setInfo : systemCpuSets) { if (setInfo.Type == CpuSetInformation) availableCpuSets.push_back(setInfo); } - std::sort(availableCpuSets.begin(), availableCpuSets.end(), [](const SYSTEM_CPU_SET_INFORMATION& a, const SYSTEM_CPU_SET_INFORMATION& b) { - if (a.CpuSet.Group != b.CpuSet.Group) return a.CpuSet.Group < b.CpuSet.Group; - return a.CpuSet.LogicalProcessorIndex < b.CpuSet.LogicalProcessorIndex; - }); - - ULONG targetCpuSetId = ULONG_MAX; - PROCESSOR_NUMBER targetProcessorNumber = {}; - bool targetFound = false; - - if (settings.idealCore >= 0 && settings.idealCore < availableCpuSets.size()) { - const auto& targetSet = availableCpuSets[settings.idealCore]; - targetProcessorNumber = { targetSet.CpuSet.Group, targetSet.CpuSet.LogicalProcessorIndex }; - targetCpuSetId = targetSet.CpuSet.Id; - targetFound = true; - LogColor(COLOR_INFO, " - 诊断: 理想核心 %d 被翻译为 (组: %d, 索引: %d)。\n", settings.idealCore, targetProcessorNumber.Group, targetProcessorNumber.Number); - LogColor(COLOR_INFO, " - 诊断: 对应的CPU Set ID为 %lu。\n", targetCpuSetId); - } - - if (targetFound) + if (targetFound) { - DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); - if (mainThreadId != 0) { - HANDLE hMainThread = OpenThread(THREAD_QUERY_INFORMATION | THREAD_SET_INFORMATION, FALSE, mainThreadId); - if (hMainThread) { - // 【修复核心】: 优先查询线程自身的CPU Sets - pGetThreadSelectedCpuSets(hMainThread, NULL, 0, &requiredSize); - if (requiredSize > 0) { - std::vector threadCpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetThreadSelectedCpuSets(hMainThread, threadCpuSetIds.data(), (ULONG)threadCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - LogColor(COLOR_INFO, " - 诊断: [线程级] 允许的CPU Set ID列表为: [ "); - for (size_t i = 0; i < threadCpuSetIds.size(); ++i) printf("%lu%s", threadCpuSetIds[i], (i == threadCpuSetIds.size() - 1) ? "" : ", "); - printf(" ]\n"); - for (ULONG allowedId : threadCpuSetIds) { if (allowedId == targetCpuSetId) { isCoreAllowed = true; break; } } - } - } - - // 如果线程没有特定设置,再回退到检查进程的默认设置 - if (!isCoreAllowed) { - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - if (requiredSize > 0) { - std::vector processCpuSetIds(requiredSize / sizeof(ULONG)); - if (pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize)) { - LogColor(COLOR_INFO, " - 诊断: [进程级] 允许的CPU Set ID列表为: [ "); - for (size_t i = 0; i < processCpuSetIds.size(); ++i) printf("%lu%s", processCpuSetIds[i], (i == processCpuSetIds.size() - 1) ? "" : ", "); - printf(" ]\n"); - for (ULONG allowedId : processCpuSetIds) { if (allowedId == targetCpuSetId) { isCoreAllowed = true; break; } } + // 获取进程实际可用的CPU Sets列表 + std::vector processCpuSetIds; + + // 首先尝试获取显式设置的CPU Sets + pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); + bool hasExplicitCpuSets = (requiredSize > 0); + + if (hasExplicitCpuSets) { + processCpuSetIds.resize(requiredSize / sizeof(ULONG)); + pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize); + LogColor(COLOR_INFO, " - 诊断: GetProcessDefaultCpuSets 返回了 %zu 个显式CPU Set ID。\n", processCpuSetIds.size()); + } else { + // 如果没有显式设置,通过亲和性掩码推导可用的CPU Sets + LogColor(COLOR_INFO, " - 诊断: 进程未设置显式CPU Sets,使用亲和性掩码推导。\n"); + + DWORD_PTR processAffinityMask, systemAffinityMask; + if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { + LogColor(COLOR_INFO, " - 诊断: 进程亲和性掩码: 0x%llX, 系统掩码: 0x%llX\n", + (unsigned long long)processAffinityMask, (unsigned long long)systemAffinityMask); + + // 遍历所有可用的CPU Sets,根据亲和性掩码筛选 + for (const auto& cpuSet : availableCpuSets) { + if (cpuSet.CpuSet.Group == 0) { + // 对于Group 0,检查亲和性掩码 + BYTE logicalIndex = cpuSet.CpuSet.LogicalProcessorIndex; + if (logicalIndex < 64 && (processAffinityMask & (static_cast(1) << logicalIndex))) { + processCpuSetIds.push_back(cpuSet.CpuSet.Id); } - } - } - - // 最终决策 - if (isCoreAllowed || settings.forceIdealCore) { - if (!isCoreAllowed) { - LogColor(COLOR_WARNING, " - 警告: 检查未通过,但根据配置强制执行 (ForceIdealCore=1)。\n"); } else { - LogColor(COLOR_SUCCESS, " - 检查通过: 理想核心 %d 在进程允许的范围内。\n", settings.idealCore); - } - if (pSetThreadIdealProcessorEx(hMainThread, &targetProcessorNumber, NULL)) { - LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 (组: %d, 索引: %d)。\n", mainThreadId, targetProcessorNumber.Group, targetProcessorNumber.Number); - idealCoreCache.insert(cacheKey); - } else { - LogColor(COLOR_ERROR, " - 失败: SetThreadIdealProcessorEx 调用失败。错误码: %lu\n", GetLastError()); + // 对于其他Group,需要使用GROUP_AFFINITY API + // 这里简化处理:如果进程亲和性==系统亲和性,说明未受限 + if (processAffinityMask == systemAffinityMask) { + processCpuSetIds.push_back(cpuSet.CpuSet.Id); + } } - } else { - LogColor(COLOR_WARNING, " - 跳过: 配置的理想核心 %d 不在线程或进程的CPU Sets允许范围内。\n", settings.idealCore); } - CloseHandle(hMainThread); + LogColor(COLOR_INFO, " - 诊断: 从亲和性掩码推导出 %zu 个可用CPU Set ID。\n", processCpuSetIds.size()); } } + + // 输出最终的CPU Sets列表 + if (!processCpuSetIds.empty()) { + LogColor(COLOR_INFO, " - 诊断: 进程实际可用的CPU Set ID列表: [ "); + for (size_t i = 0; i < processCpuSetIds.size(); ++i) + printf("%lu%s", processCpuSetIds[i], (i == processCpuSetIds.size() - 1) ? "" : ", "); + printf(" ]\n"); + + // 检查目标核心是否在可用列表中 + for (ULONG allowedId : processCpuSetIds) { + if (allowedId == targetCpuSetId) { + isCoreAllowed = true; + break; + } + } + } else { + LogColor(COLOR_WARNING, " - 警告: 无法获取进程可用的CPU Sets列表。\n"); + } } - } - } - } - } - } CloseHandle(hNewProcess); } else From ea2b9c58300f86cf22bd064fea74a43b22dcb88d Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 17:42:35 +0800 Subject: [PATCH 15/16] Add files via upload --- ForegroundBooster.cpp | 226 +++++++++++++++++++++--------------------- 1 file changed, 114 insertions(+), 112 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index bad252e..9a18c4b 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -16,10 +16,6 @@ #include #include #include -#include -#include - -std::set> idealCoreCache; #pragma comment(lib, "dwmapi.lib") #pragma comment(lib, "ntdll.lib") @@ -61,7 +57,6 @@ struct Settings int weight = -1; int processListInterval = 60; int idealCore = -1; - bool forceIdealCore = false; }; Settings settings; std::set blackList, whiteList, blackListJob; @@ -70,6 +65,10 @@ std::map originalIoPriorities; DWORD lastProcessId = 0; DWORD lastAttachedThreadId = 0; +// 用于缓存已处理或已跳过的进程,避免重复操作 +std::set> idealCoreSetCache; +std::set> idealCoreSkippedCache; + // --- 后台进程扫描缓存 --- struct ProcessInfo { @@ -211,7 +210,6 @@ void ParseIniFile(const std::wstring& path) else if (key == L"Weight") settings.weight = std::stoi(value); else if (key == L"ProcessList") settings.processListInterval = std::stoi(value); else if (key == L"IdealCore") settings.idealCore = std::stoi(value); - else if (key == L"ForceIdealCore") settings.forceIdealCore = (std::stoi(value) == 1); } } else if (currentSection == L"BlackList") @@ -335,6 +333,58 @@ void ResetAndReleaseJobObject(DWORD processId) } } +// 用于存储线程信息以便排序 +struct ThreadInfo { + DWORD threadId; + FILETIME creationTime; +}; + +// 比较函数,用于根据创建时间对线程进行排序 +bool CompareThreadsByCreationTime(const ThreadInfo& a, const ThreadInfo& b) { + // CompareFileTime 返回 -1 如果 a < b, 0 如果 a == b, 1 如果 a > b + return CompareFileTime(&a.creationTime, &b.creationTime) < 0; +} + +// 获取指定进程的第一个线程(主线程)的ID +DWORD GetProcessMainThreadId(DWORD dwProcessId) { + std::vector threads; + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) { + return 0; + } + + THREADENTRY32 te32; + te32.dwSize = sizeof(THREADENTRY32); + + if (Thread32First(hSnapshot, &te32)) { + do { + if (te32.th32OwnerProcessID == dwProcessId) { + HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID); + if (hThread) { + ThreadInfo info; + info.threadId = te32.th32ThreadID; + FILETIME exitTime, kernelTime, userTime; + if (GetThreadTimes(hThread, &info.creationTime, &exitTime, &kernelTime, &userTime)) { + threads.push_back(info); + } + CloseHandle(hThread); + } + } + } while (Thread32Next(hSnapshot, &te32)); + } + + CloseHandle(hSnapshot); + + if (threads.empty()) { + return 0; // 未找到任何线程 + } + + // 根据创建时间排序,找到最早创建的线程 + std::sort(threads.begin(), threads.end(), CompareThreadsByCreationTime); + + return threads[0].threadId; +} + void ScanAndResetIoPriorities() { LogColor(COLOR_WARNING, "[后台扫描] 已触发扫描!\n"); @@ -395,55 +445,6 @@ void ScanAndResetIoPriorities() LogColor(COLOR_INFO, "[后台扫描] 扫描完成 当前缓存 %zu 个进程\n", processCache.size()); } -// --- 新增函数: 获取进程的主线程ID --- -// 通过遍历线程并比较创建时间来找到第一个创建的线程 -DWORD GetProcessMainThreadId(DWORD dwProcessId) -{ - struct ThreadInfo { - DWORD threadId; - FILETIME creationTime; - }; - - std::vector threads; - HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) { - return 0; - } - - THREADENTRY32 te32; - te32.dwSize = sizeof(THREADENTRY32); - - if (Thread32First(hSnapshot, &te32)) { - do { - if (te32.th32OwnerProcessID == dwProcessId) { - HANDLE hThread = OpenThread(THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID); - if (hThread) { - ThreadInfo info; - info.threadId = te32.th32ThreadID; - FILETIME exitTime, kernelTime, userTime; - if (GetThreadTimes(hThread, &info.creationTime, &exitTime, &kernelTime, &userTime)) { - threads.push_back(info); - } - CloseHandle(hThread); - } - } - } while (Thread32Next(hSnapshot, &te32)); - } - - CloseHandle(hSnapshot); - - if (threads.empty()) { - return 0; - } - - // 根据创建时间排序,找到最早创建的线程 - std::sort(threads.begin(), threads.end(), [](const ThreadInfo& a, const ThreadInfo& b) { - return CompareFileTime(&a.creationTime, &b.creationTime) < 0; - }); - - return threads[0].threadId; -} - void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND hwnd, LONG idObject, LONG idChild, DWORD dwEventThread, DWORD dwmsEventTime) { if (event != EVENT_SYSTEM_FOREGROUND || !hwnd) @@ -525,67 +526,68 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND LogColor(COLOR_WARNING, " -> 进程位于作业对象黑名单中 跳过Job Object操作\n"); } } - // --- 新增: 设置主线程理想核心的逻辑 --- - if (targetFound) + // --- 新增部分开始: 设置主线程理想核心 --- + if (settings.idealCore >= 0) + { + std::pair processKey = { processNameLower, currentProcessId }; + + if (idealCoreSetCache.count(processKey)) + { + LogColor(COLOR_INFO, " -> 理想核心: 进程已在成功缓存中,跳过。\n"); + } + else if (idealCoreSkippedCache.count(processKey)) + { + LogColor(COLOR_INFO, " -> 理想核心: 进程已在跳过缓存中,跳过。\n"); + } + else + { + LogColor(COLOR_INFO, " -> 正在尝试为进程主线程设置理想核心...\n"); + DWORD_PTR processAffinity, systemAffinity; + if (GetProcessAffinityMask(hNewProcess, &processAffinity, &systemAffinity)) + { + // 检查是否设置了自定义亲和性 (如果进程亲和性与系统总亲和性不同) + // 并且理想核心不在亲和性掩码内 + if (processAffinity != systemAffinity && (processAffinity & (1ULL << settings.idealCore)) == 0) + { + LogColor(COLOR_WARNING, " - 跳过: 理想核心 %d 不在进程的自定义亲和性掩码 (%llu) 范围内。\n", settings.idealCore, processAffinity); + idealCoreSkippedCache.insert(processKey); + } + else + { + DWORD mainThreadId = GetProcessMainThreadId(currentProcessId); + if (mainThreadId != 0) + { + HANDLE hMainThread = OpenThread(THREAD_SET_INFORMATION, FALSE, mainThreadId); + if (hMainThread) { - // 获取进程实际可用的CPU Sets列表 - std::vector processCpuSetIds; - - // 首先尝试获取显式设置的CPU Sets - pGetProcessDefaultCpuSets(hNewProcess, NULL, 0, &requiredSize); - bool hasExplicitCpuSets = (requiredSize > 0); - - if (hasExplicitCpuSets) { - processCpuSetIds.resize(requiredSize / sizeof(ULONG)); - pGetProcessDefaultCpuSets(hNewProcess, processCpuSetIds.data(), (ULONG)processCpuSetIds.size() * sizeof(ULONG), &requiredSize); - LogColor(COLOR_INFO, " - 诊断: GetProcessDefaultCpuSets 返回了 %zu 个显式CPU Set ID。\n", processCpuSetIds.size()); - } else { - // 如果没有显式设置,通过亲和性掩码推导可用的CPU Sets - LogColor(COLOR_INFO, " - 诊断: 进程未设置显式CPU Sets,使用亲和性掩码推导。\n"); - - DWORD_PTR processAffinityMask, systemAffinityMask; - if (GetProcessAffinityMask(hNewProcess, &processAffinityMask, &systemAffinityMask)) { - LogColor(COLOR_INFO, " - 诊断: 进程亲和性掩码: 0x%llX, 系统掩码: 0x%llX\n", - (unsigned long long)processAffinityMask, (unsigned long long)systemAffinityMask); - - // 遍历所有可用的CPU Sets,根据亲和性掩码筛选 - for (const auto& cpuSet : availableCpuSets) { - if (cpuSet.CpuSet.Group == 0) { - // 对于Group 0,检查亲和性掩码 - BYTE logicalIndex = cpuSet.CpuSet.LogicalProcessorIndex; - if (logicalIndex < 64 && (processAffinityMask & (static_cast(1) << logicalIndex))) { - processCpuSetIds.push_back(cpuSet.CpuSet.Id); - } - } else { - // 对于其他Group,需要使用GROUP_AFFINITY API - // 这里简化处理:如果进程亲和性==系统亲和性,说明未受限 - if (processAffinityMask == systemAffinityMask) { - processCpuSetIds.push_back(cpuSet.CpuSet.Id); - } - } - } - LogColor(COLOR_INFO, " - 诊断: 从亲和性掩码推导出 %zu 个可用CPU Set ID。\n", processCpuSetIds.size()); - } + if (SetThreadIdealProcessor(hMainThread, settings.idealCore) != (DWORD)-1) + { + LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 %d。\n", mainThreadId, settings.idealCore); + idealCoreSetCache.insert(processKey); } - - // 输出最终的CPU Sets列表 - if (!processCpuSetIds.empty()) { - LogColor(COLOR_INFO, " - 诊断: 进程实际可用的CPU Set ID列表: [ "); - for (size_t i = 0; i < processCpuSetIds.size(); ++i) - printf("%lu%s", processCpuSetIds[i], (i == processCpuSetIds.size() - 1) ? "" : ", "); - printf(" ]\n"); - - // 检查目标核心是否在可用列表中 - for (ULONG allowedId : processCpuSetIds) { - if (allowedId == targetCpuSetId) { - isCoreAllowed = true; - break; - } - } - } else { - LogColor(COLOR_WARNING, " - 警告: 无法获取进程可用的CPU Sets列表。\n"); + else + { + LogColor(COLOR_ERROR, " - 失败: 调用 SetThreadIdealProcessor 失败。错误码: %lu\n", GetLastError()); } + CloseHandle(hMainThread); + } + else + { + LogColor(COLOR_ERROR, " - 失败: 无法打开主线程句柄。错误码: %lu\n", GetLastError()); } + } + else + { + LogColor(COLOR_ERROR, " - 失败: 无法找到进程的主线程。\n"); + } + } + } + else + { + LogColor(COLOR_ERROR, " - 失败: 无法获取进程亲和性掩码。错误码: %lu\n", GetLastError()); + } + } + } CloseHandle(hNewProcess); } else From 70b3419857ba99bcf157fe3b64d9966eba50b4e8 Mon Sep 17 00:00:00 2001 From: signin404 <145902543+signin404@users.noreply.github.com> Date: Thu, 6 Nov 2025 18:04:09 +0800 Subject: [PATCH 16/16] Add files via upload --- ForegroundBooster.cpp | 22 +++++++++++----------- ForegroundBooster.ini | 29 ++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/ForegroundBooster.cpp b/ForegroundBooster.cpp index 9a18c4b..fc94c8f 100644 --- a/ForegroundBooster.cpp +++ b/ForegroundBooster.cpp @@ -65,7 +65,7 @@ std::map originalIoPriorities; DWORD lastProcessId = 0; DWORD lastAttachedThreadId = 0; -// 用于缓存已处理或已跳过的进程,避免重复操作 +// 用于缓存已处理或已跳过的进程 避免重复操作 std::set> idealCoreSetCache; std::set> idealCoreSkippedCache; @@ -339,7 +339,7 @@ struct ThreadInfo { FILETIME creationTime; }; -// 比较函数,用于根据创建时间对线程进行排序 +// 比较函数 用于根据创建时间对线程进行排序 bool CompareThreadsByCreationTime(const ThreadInfo& a, const ThreadInfo& b) { // CompareFileTime 返回 -1 如果 a < b, 0 如果 a == b, 1 如果 a > b return CompareFileTime(&a.creationTime, &b.creationTime) < 0; @@ -379,7 +379,7 @@ DWORD GetProcessMainThreadId(DWORD dwProcessId) { return 0; // 未找到任何线程 } - // 根据创建时间排序,找到最早创建的线程 + // 根据创建时间排序 找到最早创建的线程 std::sort(threads.begin(), threads.end(), CompareThreadsByCreationTime); return threads[0].threadId; @@ -533,11 +533,11 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND if (idealCoreSetCache.count(processKey)) { - LogColor(COLOR_INFO, " -> 理想核心: 进程已在成功缓存中,跳过。\n"); + LogColor(COLOR_INFO, " -> 理想核心: 进程已在成功缓存中 跳过\n"); } else if (idealCoreSkippedCache.count(processKey)) { - LogColor(COLOR_INFO, " -> 理想核心: 进程已在跳过缓存中,跳过。\n"); + LogColor(COLOR_INFO, " -> 理想核心: 进程已在跳过缓存中 跳过\n"); } else { @@ -549,7 +549,7 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND // 并且理想核心不在亲和性掩码内 if (processAffinity != systemAffinity && (processAffinity & (1ULL << settings.idealCore)) == 0) { - LogColor(COLOR_WARNING, " - 跳过: 理想核心 %d 不在进程的自定义亲和性掩码 (%llu) 范围内。\n", settings.idealCore, processAffinity); + LogColor(COLOR_WARNING, " - 跳过: 理想核心 %d 不在亲和性 (%llu) 范围内\n", settings.idealCore, processAffinity); idealCoreSkippedCache.insert(processKey); } else @@ -562,29 +562,29 @@ void CALLBACK ForegroundEventProc(HWINEVENTHOOK hWinEventHook, DWORD event, HWND { if (SetThreadIdealProcessor(hMainThread, settings.idealCore) != (DWORD)-1) { - LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 %d。\n", mainThreadId, settings.idealCore); + LogColor(COLOR_SUCCESS, " - 成功: 已将主线程 %lu 的理想核心设置为 %d\n", mainThreadId, settings.idealCore); idealCoreSetCache.insert(processKey); } else { - LogColor(COLOR_ERROR, " - 失败: 调用 SetThreadIdealProcessor 失败。错误码: %lu\n", GetLastError()); + LogColor(COLOR_ERROR, " - 失败: 调用 SetThreadIdealProcessor 失败 错误码: %lu\n", GetLastError()); } CloseHandle(hMainThread); } else { - LogColor(COLOR_ERROR, " - 失败: 无法打开主线程句柄。错误码: %lu\n", GetLastError()); + LogColor(COLOR_ERROR, " - 失败: 无法打开主线程句柄 错误码: %lu\n", GetLastError()); } } else { - LogColor(COLOR_ERROR, " - 失败: 无法找到进程的主线程。\n"); + LogColor(COLOR_ERROR, " - 失败: 无法找到进程的主线程\n"); } } } else { - LogColor(COLOR_ERROR, " - 失败: 无法获取进程亲和性掩码。错误码: %lu\n", GetLastError()); + LogColor(COLOR_ERROR, " - 失败: 无法获取进程亲和性掩码 错误码: %lu\n", GetLastError()); } } } diff --git a/ForegroundBooster.ini b/ForegroundBooster.ini index 17cc0f1..f7b11c5 100644 --- a/ForegroundBooster.ini +++ b/ForegroundBooster.ini @@ -1,9 +1,6 @@ [Settings] -;进程列表检测间隔 -ProcessList=60 - -;应用间隔 -DwmEnableMMCSS=60 +;主线程理想核心 +IdealCore=2 ;调度优先级 ;值:0-9 @@ -11,11 +8,17 @@ DwmEnableMMCSS=60 ;时间片权重 ;值:1-9 -;Weight=1 +;Weight=9 ;数据包优先级 ;值:0-63 -DSCP=46 +;DSCP=46 + +;进程列表检测间隔 +ProcessList=60 + +;DWM-MMCSS应用间隔 +DwmEnableMMCSS=60 [WhiteList] ;附加到前台线程 @@ -42,7 +45,19 @@ taskhostw.exe TextInputHost.exe wininit.exe winlogon.exe +;用户进程 +foobar2000.exe [BlackListJob] ;作业对象黑名单 +cmd.exe +powershell.exe +explorer.exe +;用户进程 +XYplorer.exe +ProcessLasso.exe chrome.exe +Listary.exe +everything.exe +NSudoLG.exe +SandMan.exe