Skip to content

Commit ce517b6

Browse files
author
LocalIdentity
committed
Add support for hidden CMD window
Adds support for a hidden CMD window so we can use it to replace the CMD window that flashes when we update the runtime files
1 parent 0cc1451 commit ce517b6

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

engine/system/sys_main.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class sys_IMain {
7878
virtual char* ClipboardPaste() = 0;
7979
virtual bool SetWorkDir(std::filesystem::path const& newCwd = {}) = 0;
8080
virtual void SpawnProcess(std::filesystem::path cmdName, const char* argList) = 0;
81+
virtual void SpawnProcessHidden(std::filesystem::path cmdName, const char* argList) = 0;
8182
virtual std::optional<std::string> OpenURL(const char* url) = 0;
8283
virtual void Error(const char* fmt, ...) = 0;
8384
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+
void SpawnProcessHidden(std::filesystem::path cmdName, const char* argList);
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: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include <map>
3434
#include <set>
3535
#include <thread>
36+
#include <vector>
3637

3738
#include <fmt/core.h>
3839

@@ -434,6 +435,61 @@ void sys_main_c::SpawnProcess(std::filesystem::path cmdName, const char* argList
434435
#endif
435436
}
436437

438+
void sys_main_c::SpawnProcessHidden(std::filesystem::path cmdName, const char* argList)
439+
{
440+
#ifdef _WIN32
441+
if (!cmdName.has_extension()) {
442+
cmdName.replace_extension(".exe");
443+
}
444+
auto fileStr = cmdName.wstring();
445+
const char* safeArgs = argList ? argList : "";
446+
wchar_t* wideArgs = (*safeArgs != '\0') ? WidenUTF8String(safeArgs) : nullptr;
447+
std::wstring commandLine = L"\"" + fileStr + L"\"";
448+
if (wideArgs) {
449+
commandLine.push_back(L' ');
450+
commandLine.append(wideArgs);
451+
}
452+
std::vector<wchar_t> commandBuffer(commandLine.begin(), commandLine.end());
453+
commandBuffer.push_back(L'\0');
454+
std::wstring workingDir;
455+
if (cmdName.has_parent_path()) {
456+
workingDir = cmdName.parent_path().wstring();
457+
}
458+
STARTUPINFOW si{};
459+
PROCESS_INFORMATION pi{};
460+
si.cb = sizeof(si);
461+
si.dwFlags = STARTF_USESHOWWINDOW;
462+
si.wShowWindow = SW_HIDE;
463+
BOOL created = CreateProcessW(
464+
nullptr,
465+
commandBuffer.data(),
466+
nullptr,
467+
nullptr,
468+
FALSE,
469+
CREATE_NO_WINDOW,
470+
nullptr,
471+
workingDir.empty() ? nullptr : workingDir.data(),
472+
&si,
473+
&pi
474+
);
475+
if (wideArgs) {
476+
FreeWideString(wideArgs);
477+
}
478+
if (!created) {
479+
DWORD err = GetLastError();
480+
if (con) {
481+
con->Printf("^1CreateProcessW failed with code %lu, falling back to ShellExecute.^0\n", static_cast<unsigned long>(err));
482+
}
483+
SpawnProcess(cmdName, argList);
484+
return;
485+
}
486+
CloseHandle(pi.hThread);
487+
CloseHandle(pi.hProcess);
488+
#else
489+
SpawnProcess(cmdName, argList);
490+
#endif
491+
}
492+
437493
std::string GetWineHostVersion()
438494
{
439495
#ifdef _WIN32

ui_api.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
** ConPrintTable(table[, noRecurse])
102102
** ConExecute("<cmd>")
103103
** SpawnProcess("<cmdName>"[, "<args>"])
104+
** SpawnProcessHidden("<cmdName>"[, "<args>"])
104105
** err = OpenURL("<url>")
105106
** SetProfiling(isEnabled)
106107
** Restart()
@@ -2017,6 +2018,18 @@ static int l_SpawnProcess(lua_State* L)
20172018
return 0;
20182019
}
20192020

2021+
static int l_SpawnProcessHidden(lua_State* L)
2022+
{
2023+
ui_main_c* ui = GetUIPtr(L);
2024+
int n = lua_gettop(L);
2025+
ui->LAssert(L, n >= 1, "Usage: SpawnProcessHidden(cmdName[, args])");
2026+
ui->LAssert(L, lua_isstring(L, 1), "SpawnProcessHidden() argument 1: expected string, got %s", luaL_typename(L, 1));
2027+
auto cmdPath = std::filesystem::u8path(lua_tostring(L, 1));
2028+
auto args = lua_tostring(L, 2);
2029+
ui->sys->SpawnProcessHidden(cmdPath, args);
2030+
return 0;
2031+
}
2032+
20202033
static int l_OpenURL(lua_State* L)
20212034
{
20222035
ui_main_c* ui = GetUIPtr(L);
@@ -2249,6 +2262,7 @@ int ui_main_c::InitAPI(lua_State* L)
22492262
ADDFUNC(ConClear);
22502263
ADDFUNC(print);
22512264
ADDFUNC(SpawnProcess);
2265+
ADDFUNC(SpawnProcessHidden);
22522266
ADDFUNC(OpenURL);
22532267
ADDFUNC(SetProfiling);
22542268
ADDFUNC(TakeScreenshot);

0 commit comments

Comments
 (0)