Merge pull request #9104 from JosJuice/cmd-unicode

DolphinQt: Handle non-ASCII characters in Windows cmd arguments
This commit is contained in:
Léo Lam 2020-10-20 01:45:28 +02:00 committed by GitHub
commit 98875346bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 48 additions and 25 deletions

View File

@ -31,6 +31,7 @@
#ifdef _WIN32
#include <Windows.h>
#include <shellapi.h>
constexpr u32 CODEPAGE_SHIFT_JIS = 932;
constexpr u32 CODEPAGE_WINDOWS_1252 = 1252;
#else
@ -630,3 +631,22 @@ std::string PathToString(const std::filesystem::path& path)
#endif
}
#endif
#ifdef _WIN32
std::vector<std::string> CommandLineToUtf8Argv(const wchar_t* command_line)
{
int nargs;
LPWSTR* tokenized = CommandLineToArgvW(command_line, &nargs);
if (!tokenized)
return {};
std::vector<std::string> argv(nargs);
for (size_t i = 0; i < nargs; ++i)
{
argv[i] = WStringToUTF8(tokenized[i]);
}
LocalFree(tokenized);
return argv;
}
#endif

View File

@ -236,3 +236,7 @@ inline bool IsPrintableCharacter(char c)
{
return std::isprint(c, std::locale::classic());
}
#ifdef _WIN32
std::vector<std::string> CommandLineToUtf8Argv(const wchar_t* command_line);
#endif

View File

@ -3,6 +3,9 @@
// Refer to the license.txt file included.
#ifdef _WIN32
#include <string>
#include <vector>
#include <Windows.h>
#include <cstdio>
#endif
@ -96,11 +99,18 @@ static bool QtMsgAlertHandler(const char* caption, const char* text, bool yes_no
return false;
}
// N.B. On Windows, this should be called from WinMain. Link against qtmain and specify
// /SubSystem:Windows
#ifndef _WIN32
int main(int argc, char* argv[])
{
#ifdef _WIN32
#else
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
std::vector<std::string> utf8_args = CommandLineToUtf8Argv(GetCommandLineW());
const int utf8_argc = static_cast<int>(utf8_args.size());
std::vector<char*> utf8_argv(utf8_args.size());
for (size_t i = 0; i < utf8_args.size(); ++i)
utf8_argv[i] = utf8_args[i].data();
const bool console_attached = AttachConsole(ATTACH_PARENT_PROCESS) != FALSE;
HANDLE stdout_handle = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (console_attached && stdout_handle)
@ -123,7 +133,12 @@ int main(int argc, char* argv[])
#endif
auto parser = CommandLineParse::CreateParser(CommandLineParse::ParserOptions::IncludeGUIOptions);
const optparse::Values& options = CommandLineParse::ParseArguments(parser.get(), argc, argv);
const optparse::Values& options =
#ifdef _WIN32
CommandLineParse::ParseArguments(parser.get(), utf8_argc, utf8_argv.data());
#else
CommandLineParse::ParseArguments(parser.get(), argc, argv);
#endif
const std::vector<std::string> args = parser->args();
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
@ -132,7 +147,11 @@ int main(int argc, char* argv[])
QCoreApplication::setOrganizationDomain(QStringLiteral("dolphin-emu.org"));
QCoreApplication::setApplicationName(QStringLiteral("dolphin-emu"));
#ifdef _WIN32
QApplication app(__argc, __argv);
#else
QApplication app(argc, argv);
#endif
#ifdef _WIN32
// On Windows, Qt 5's default system font (MS Shell Dlg 2) is outdated.

View File

@ -16,26 +16,6 @@
#include "UpdaterCommon/UI.h"
#include "UpdaterCommon/UpdaterCommon.h"
namespace
{
std::vector<std::string> CommandLineToUtf8Argv(PCWSTR command_line)
{
int nargs;
LPWSTR* tokenized = CommandLineToArgvW(command_line, &nargs);
if (!tokenized)
return {};
std::vector<std::string> argv(nargs);
for (int i = 0; i < nargs; ++i)
{
argv[i] = WStringToUTF8(tokenized[i]);
}
LocalFree(tokenized);
return argv;
}
}; // namespace
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
if (lstrlenW(pCmdLine) == 0)

View File

@ -35,7 +35,7 @@
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(QtLibDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>qtmain$(QtLibSuffix).lib;Qt5Core$(QtLibSuffix).lib;Qt5Gui$(QtLibSuffix).lib;Qt5Widgets$(QtLibSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>Qt5Core$(QtLibSuffix).lib;Qt5Gui$(QtLibSuffix).lib;Qt5Widgets$(QtLibSuffix).lib;%(AdditionalDependencies)</AdditionalDependencies>
<SubSystem>Windows</SubSystem>
<!--
<AdditionalOptions>"/manifestdependency:type='Win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\" %(AdditionalOptions)</AdditionalOptions>