From c4695b8cf10faabe69fce8f8971d034678453886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 12 Aug 2026 10:29:29 +0800 Subject: [PATCH] Processing (Windows): sets `LANG=C` when spawning child processes --- src/common/impl/processing_windows.c | 56 +++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/common/impl/processing_windows.c b/src/common/impl/processing_windows.c index 5df9f9057..c3f579261 100644 --- a/src/common/impl/processing_windows.c +++ b/src/common/impl/processing_windows.c @@ -48,6 +48,41 @@ static void argvToCmdline(char* const argv[], FFstrbuf* result) { } } +static wchar_t* createChildEnvironment(void) { + wchar_t* source = GetEnvironmentStringsW(); + if (!source) { + return nullptr; + } + + size_t sourceLength = 0; + for (const wchar_t* entry = source; *entry; entry += wcslen(entry) + 1) { + sourceLength += wcslen(entry) + 1; + } + + wchar_t* result = malloc((sourceLength + 7) * sizeof(wchar_t)); + wchar_t* write = result; + bool foundLang = false; + for (const wchar_t* entry = source; *entry; entry += wcslen(entry) + 1) { + if (_wcsnicmp(entry, L"LANG=", 5) == 0) { + wcscpy(write, L"LANG=C"); + write += 6; + foundLang = true; + } else { + size_t entryLength = wcslen(entry) + 1; + memcpy(write, entry, entryLength * sizeof(wchar_t)); + write += entryLength; + } + } + if (!foundLang) { + wcscpy(write, L"LANG=C"); + write += 6; + } + *write = L'\0'; + + FreeEnvironmentStringsW(source); + return result; +} + const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* outHandle) { const int32_t timeout = instance.config.general.processingTimeout; @@ -108,17 +143,18 @@ const char* ffProcessSpawn(char* const argv[], bool useStdErr, FFProcessHandle* } } + FF_AUTO_FREE wchar_t* environment = createChildEnvironment(); BOOL success = CreateProcessW( - nullptr, // application name - cmdline, // command line - nullptr, // process security attributes - nullptr, // primary thread security attributes - TRUE, // handles are inherited - 0, // creation flags - nullptr, // use parent's environment - nullptr, // use parent's current directory - &siStartInfo, // STARTUPINFO pointer - &piProcInfo // receives PROCESS_INFORMATION + nullptr, // application name + cmdline, // command line + nullptr, // process security attributes + nullptr, // primary thread security attributes + TRUE, // handles are inherited + CREATE_UNICODE_ENVIRONMENT, // creation flags + environment, // child environment + nullptr, // use parent's current directory + &siStartInfo, // STARTUPINFO pointer + &piProcInfo // receives PROCESS_INFORMATION ); NtClose(hChildPipeWrite);