Skip to content

Commit 9b22671

Browse files
author
LocalIdentity
committed
PoB Process count
The new `GetProcessCount` helper (sys_main.cpp:438) walks the system process list via Windows’ Toolhelp API—no external commands. It creates a snapshot with `CreateToolhelp32Snapshot`, iterates `PROCESSENTRY32W`, lowercases each executable name, and increments a counter whenever the name matches one of the PoB executable variants passed in from Lua. That count flows back through the Lua binding (ui_api.cpp:2024) up to `getMatchingProcessCount` in src/Launch.lua:20, so the updater knows exactly how many sibling PoB processes are running.
1 parent 0cc1451 commit 9b22671

File tree

4 files changed

+71
-0
lines changed

4 files changed

+71
-0
lines changed

engine/system/sys_main.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <filesystem>
88
#include <optional>
99
#include <string>
10+
#include <vector>
1011

1112
// =======
1213
// Classes
@@ -78,6 +79,7 @@ class sys_IMain {
7879
virtual char* ClipboardPaste() = 0;
7980
virtual bool SetWorkDir(std::filesystem::path const& newCwd = {}) = 0;
8081
virtual void SpawnProcess(std::filesystem::path cmdName, const char* argList) = 0;
82+
virtual int GetProcessCount(const std::vector<std::wstring>& imageNames) = 0;
8183
virtual std::optional<std::string> OpenURL(const char* url) = 0;
8284
virtual void Error(const char* fmt, ...) = 0;
8385
virtual void Exit(const char* msg = NULL) = 0;

engine/system/win/sys_local.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class sys_main_c: public sys_IMain {
3737
char* ClipboardPaste();
3838
bool SetWorkDir(std::filesystem::path const& newCwd = {});
3939
void SpawnProcess(std::filesystem::path cmdName, const char* argList);
40+
int GetProcessCount(const std::vector<std::wstring>& imageNames);
4041
std::optional<std::string> OpenURL(const char* url); // return value has failure reason
4142
void Error(const char* fmt, ...);
4243
void Exit(const char* msg = NULL);

engine/system/win/sys_main.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#ifdef _WIN32
1616
#include <eh.h>
1717
#include <Shlobj.h>
18+
#include <TlHelp32.h>
1819
#elif __linux__
1920
#include <unistd.h>
2021
#include <limits.h>
@@ -35,6 +36,9 @@
3536
#include <thread>
3637

3738
#include <fmt/core.h>
39+
#include <algorithm>
40+
#include <cwctype>
41+
#include <unordered_set>
3842

3943
// ======
4044
// Locals
@@ -434,6 +438,47 @@ void sys_main_c::SpawnProcess(std::filesystem::path cmdName, const char* argList
434438
#endif
435439
}
436440

441+
int sys_main_c::GetProcessCount(const std::vector<std::wstring>& imageNames)
442+
{
443+
#ifdef _WIN32
444+
if (imageNames.empty()) {
445+
return 0;
446+
}
447+
std::unordered_set<std::wstring> lookup;
448+
lookup.reserve(imageNames.size());
449+
for (const auto& name : imageNames) {
450+
std::wstring lowered = name;
451+
std::transform(lowered.begin(), lowered.end(), lowered.begin(), [](wchar_t c) {
452+
return std::towlower(c);
453+
});
454+
lookup.insert(std::move(lowered));
455+
}
456+
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
457+
if (snapshot == INVALID_HANDLE_VALUE) {
458+
return -1;
459+
}
460+
PROCESSENTRY32W entry{};
461+
entry.dwSize = sizeof(entry);
462+
int count = 0;
463+
if (Process32FirstW(snapshot, &entry)) {
464+
do {
465+
std::wstring exe(entry.szExeFile);
466+
std::transform(exe.begin(), exe.end(), exe.begin(), [](wchar_t c) {
467+
return std::towlower(c);
468+
});
469+
if (lookup.find(exe) != lookup.end()) {
470+
++count;
471+
}
472+
} while (Process32NextW(snapshot, &entry));
473+
}
474+
CloseHandle(snapshot);
475+
return count;
476+
#else
477+
(void)imageNames;
478+
return -1;
479+
#endif
480+
}
481+
437482
std::string GetWineHostVersion()
438483
{
439484
#ifdef _WIN32

ui_api.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <fstream>
1111
#include <zlib.h>
1212
#include <cmath>
13+
#include <vector>
1314

1415
#include "core/core_tex_manipulation.h"
1516

@@ -101,6 +102,7 @@
101102
** ConPrintTable(table[, noRecurse])
102103
** ConExecute("<cmd>")
103104
** SpawnProcess("<cmdName>"[, "<args>"])
105+
** count = GetProcessCount({"<image1>", ...})
104106
** err = OpenURL("<url>")
105107
** SetProfiling(isEnabled)
106108
** Restart()
@@ -2017,6 +2019,26 @@ static int l_SpawnProcess(lua_State* L)
20172019
return 0;
20182020
}
20192021

2022+
static int l_GetProcessCount(lua_State* L)
2023+
{
2024+
ui_main_c* ui = GetUIPtr(L);
2025+
ui->LAssert(L, lua_gettop(L) >= 1, "Usage: GetProcessCount(names)");
2026+
ui->LAssert(L, lua_istable(L, 1), "GetProcessCount() argument 1: expected table, got %s", luaL_typename(L, 1));
2027+
std::vector<std::wstring> names;
2028+
size_t len = lua_rawlen(L, 1);
2029+
names.reserve(len);
2030+
for (size_t i = 1; i <= len; ++i) {
2031+
lua_rawgeti(L, 1, static_cast<int>(i));
2032+
ui->LAssert(L, lua_isstring(L, -1), "GetProcessCount() table values must be strings, got %s", luaL_typename(L, -1));
2033+
auto name = lua_tostring(L, -1);
2034+
names.emplace_back(std::filesystem::u8path(name).wstring());
2035+
lua_pop(L, 1);
2036+
}
2037+
int count = ui->sys->GetProcessCount(names);
2038+
lua_pushinteger(L, count);
2039+
return 1;
2040+
}
2041+
20202042
static int l_OpenURL(lua_State* L)
20212043
{
20222044
ui_main_c* ui = GetUIPtr(L);
@@ -2249,6 +2271,7 @@ int ui_main_c::InitAPI(lua_State* L)
22492271
ADDFUNC(ConClear);
22502272
ADDFUNC(print);
22512273
ADDFUNC(SpawnProcess);
2274+
ADDFUNC(GetProcessCount);
22522275
ADDFUNC(OpenURL);
22532276
ADDFUNC(SetProfiling);
22542277
ADDFUNC(TakeScreenshot);

0 commit comments

Comments
 (0)