Entrypoint/Win32: just use __argc and __argv if available

We were splitting the Unicode command-line using CommandLineToArgvW(),
then converting to 8-bit for argv. That was practically always the same
as what the runtime had already stored in __argv. But not always: it
looks like the runtime splits the 8-bit command-line (GetCommandLineA())
and there are certain Unicode characters that WideCharToMultiByte()
converts to a quote ("), which causes the command-line splitter to
differ from what Qt is doing.

__argv may not always be populated, if the user requested a wmain()
somehow, because that causes __wargv to be populated. Therefore, we need
to keep the old code.

[ChangeLog][QtGui] Fixed a bug that caused Qt applications to disregard
Unicode command-lines on Windows even when argc and argv were passed un-
modified to QGuiApplication or QApplication. This happened only for
builds with Visual Studio and in the "windows" subsystem (not
"console").

Pick-to: 6.5
Fixes: QTBUG-125380
Change-Id: If05cb740b64f42eba21efffd17d007799f99d8bf
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit 993b197d9c944060763fb46514c5c1d31abce205)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit 34533705b27838d1507f1267cdf55ce6a399b225)
This commit is contained in:
Thiago Macieira 2024-05-16 10:14:36 -07:00 committed by Qt Cherry-pick Bot
parent 9c1096f4f6
commit a5fdbd73a9

View File

@ -1,6 +1,7 @@
// Copyright (C) 2019 The Qt Company Ltd. // Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <stdlib.h> // __argc, __argv
#include <qt_windows.h> #include <qt_windows.h>
#include <shellapi.h> #include <shellapi.h>
@ -38,11 +39,14 @@ static inline char *wideToMulti(unsigned int codePage, const wchar_t *aw)
static inline int qtEntryPoint() static inline int qtEntryPoint()
{ {
int argc = 0; int argc = __argc;
char **argv = __argv;
if (argv)
return main(argc, argv);
wchar_t **argvW = CommandLineToArgvW(GetCommandLineW(), &argc); wchar_t **argvW = CommandLineToArgvW(GetCommandLineW(), &argc);
if (argvW == nullptr) if (argvW == nullptr)
return -1; return -1;
char **argv = new char *[argc + 1]; argv = new char *[argc + 1];
for (int i = 0; i != argc; ++i) for (int i = 0; i != argc; ++i)
argv[i] = wideToMulti(CP_ACP, argvW[i]); argv[i] = wideToMulti(CP_ACP, argvW[i]);
argv[argc] = nullptr; argv[argc] = nullptr;