fix(win): route shell-outs through a windowless helper (no cmd.exe flash)

_popen/_popen-style shell-outs flash a cmd.exe console window on Windows. Add
Platform::runHiddenCapture() — CreateProcess + CREATE_NO_WINDOW capturing stdout on
Windows, popen on POSIX — and route the remaining shell-outs through it:
- GPU-aware idle detection (getGpuUtilization: "where nvidia-smi" / "nvidia-smi --query-gpu")
- xmrig discovery + version (findXmrigBinary "where xmrig.exe"; "<bin> --version", stderr merged)
- wallet-rebuild helper (app_network) — keeps its exit-code check via the new exitCode out-param

None of these are on the launch path (that was the daemon spawn, fixed in a2f84be); each
would flash a console only when it ran (idle-GPU mining, mining tab, wallet recovery).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-30 23:58:54 -05:00
co-authored by Claude Opus 4.8
parent a2f84be2d4
commit 0942691eb3
4 changed files with 101 additions and 71 deletions
+6 -15
View File
@@ -5043,21 +5043,12 @@ void App::rebuildWalletDatabase()
const std::string tmpOut = datadir + "/wallet.rebuilt-" + std::string(ts) + ".tmp";
{ std::error_code ec; fs::remove(tmpOut, ec); } // helper uses DB_EXCL — path must be fresh
// 3. Run the helper (src -> tmpOut). Quote both paths; capture its JSON line.
std::string cmd = "\"" + helper + "\" \"" + src + "\" \"" + tmpOut + "\"";
#ifdef _WIN32
cmd = "\"" + cmd + "\""; // cmd.exe strips the outermost quotes
FILE* fp = _popen(cmd.c_str(), "r");
#else
FILE* fp = popen(cmd.c_str(), "r");
#endif
std::string jout;
if (fp) { char b[512]; while (std::fgets(b, sizeof b, fp)) jout += b; }
#ifdef _WIN32
const int rc = fp ? _pclose(fp) : -1;
#else
const int rc = fp ? pclose(fp) : -1;
#endif
// 3. Run the helper (src -> tmpOut). Quote both paths; capture its JSON line. Windowless
// (runHiddenCapture) so a wallet rebuild never flashes a cmd.exe console; it runs the
// helper via CreateProcess directly on Windows, so no cmd.exe outer-quote wrap is needed.
const std::string cmd = "\"" + helper + "\" \"" + src + "\" \"" + tmpOut + "\"";
int rc = -1;
const std::string jout = util::Platform::runHiddenCapture(cmd, /*mergeStderr=*/false, &rc);
DEBUG_LOGF("[App] wallet-rebuild helper rc=%d out=%s\n", rc, jout.c_str());
// 4. Verify-before-swap: the output must be a readable BDB with the fund-critical keys.