Issue 1:
My config file:

{

"acrylicOpacity" : 0.75,

"closeOnExit" : false,

"colorScheme" : "Campbell",

"commandline" : "cmd.exe /k "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"",

"cursorColor" : "#FFFFFF",

"cursorShape" : "bar",

"fontFace" : "Consolas",

"fontSize" : 12,

"guid" : "{e319bb19-0ab7-4f16-a7a2-b76c321d50c2}",

"historySize" : 9001,

"name" : "x64 Native Tools Command Prompt for VS 2019",

"padding" : "0, 0, 0, 0",

"snapOnInput" : true,

"useAcrylic" : true,

"backgroundImage":"‪D:\Pictures\star.png"

}

Outout:

'C:\Program' 不是内部或外部命令，也不是可运行的程序

Issue 2:
Environment

Windows build number: [run "ver" at a command prompt]
Windows Terminal version (if applicable):

Any other software?

Today I modified the Windows Terminal configuration file and wanted to create a Pwsh with the emoji title. However, I encountered some confusion in this process. I checked the task manager and found that conhost did not escape when the process was started, causing the command line to parse the exception.

Steps to reproduce

Expected behavior

I need to start pwsh by the following command line (note that the following command line is in cmd, or you can start pwsh normally using CreateProcessW.)

"C:\Program Files\PowerShell\7-preview\pwsh.exe" -NoExit -Command "$Host.UI.RawUI.WindowTitle=\"Windows Pwsh 💙 (7 Preview)\""

Here is the Windows Terminal configuration file (the command line has been properly escaped):

{
"startingDirectory": "C:\\Users\\CharlieInc",
"guid": "{08a0be98-ff68-4e3a-a054-0fbd3969d3bb}",
"name": "Windows Pwsh 💙 (7 Preview)",
"colorscheme": "Campbell",
"historySize": 9001,
"snapOnInput": true,
"cursorColor": "#FFFFFF",
"cursorShape": "bar",
"commandline": "\"C:\\Program Files\\PowerShell\\7-preview\\pwsh.exe\" -NoExit -Command \"$Host.UI.RawUI.WindowTitle=\\\"Windows Pwsh 💙 (7 Preview)\\\"\"",
"fontFace": "Consolas",
"fontSize": 12,
"acrylicOpacity": 0.75,
"useAcrylic": true,
"closeOnExit": false,
"padding": "0, 0, 0, 0",
"icon": "ms-appdata:///roaming/pwsh-32.png"
}

Actual behavior

As expected, Pwsh should set the title correctly, but pwsh reported the error:

Let's take a look at the command line:

When you see the red line, the command line that pwsh starts is incorrect, and when you start conhost, the command line is still correct!

Currently I have found a suspicious code, most likely this code caused an error:

terminal/src/host/ConsoleArguments.cpp

Lines 263 to 288
in
71e19cd

HRESULT ConsoleArguments::_GetClientCommandline(_Inout_ std::vector<std::wstring>& args, const size_t index, const bool skipFirst)

{

auto start = args.begin()+index;

// Erase the first token.

// Used to get rid of the explicit commandline token "--"

if (skipFirst)

{

// Make sure that the arg we're deleting is "--"

FAIL_FAST_IF(!(CLIENT_COMMANDLINE_ARG == start->c_str()));

args.erase(start);

}

_clientCommandline = L"";

size_t j = 0;

for (j = index; j < args.size(); j++)

{

_clientCommandline += args[j];

if (j+1 < args.size())

{

_clientCommandline += L" ";

}

}

args.erase(args.begin()+index, args.begin()+j);

return S_OK;

In this code, command line composition is simply a simple connection rather than a concatenated string. If the string contains spaces, this will result in an incorrect command line.

Below is a code for the command line escaping, which may be useful：

inline std::wstring escape_argument(std::wstring_view ac) {
if (ac.empty()) {
return L"\"\"";
}
bool hasspace = false;
auto n = ac.size();
for (auto c : ac) {
switch (c) {
case L'"':
case L'\\':
n++;
break;
case ' ':
case '\t':
hasspace = true;
break;
default:
break;
}
}
if (hasspace) {
n += 2;
}
if (n == ac.size()) {
return std::wstring(ac.data(), ac.size());
}
std::wstring buf;
if (hasspace) {
buf.push_back(L'"');
}
size_t slashes = 0;
for (auto c : ac) {
switch (c) {
case L'\\':
slashes++;
buf.push_back(L'\\');
break;
case L'"': {
for (; slashes > 0; slashes--) {
buf.push_back(L'\\');
}
buf.push_back(L'\\');
buf.push_back(c);
} break;
default:
slashes = 0;
buf.push_back(c);
break;
}
}
if (hasspace) {
for (; slashes > 0; slashes--) {
buf.push_back(L'\\');
}
buf.push_back(L'"');
}
return buf;
}