Improve VS profile generation (#19025)

* Make PowerShell profile generation try to find `pwsh.exe` before
falling back to legacy powershell
* Make profiles generated on an `arm64` host work properly

## Validation Steps Performed

* Local build ran
* Verified the new `arm64` profile works
* Verified `pwsh.exe` is used if present
* Verified `powershell.exe` is used if `pwsh` is not present in path
* Verified we don't attempt to create `arm64` host cmd/pwsh profiles if
VS is not >= 17.4
This commit is contained in:
Katherine Reynolds 2025-06-13 15:41:10 -07:00 committed by GitHub
parent 685499df3a
commit bb62ce9345
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 40 additions and 6 deletions

View File

@ -45,7 +45,15 @@ std::wstring VsDevCmdGenerator::GetProfileCommandLine(const VsSetupConfiguration
// The "-startdir" parameter will prevent "vsdevcmd" from automatically
// setting the shell path so the path in the profile will be used instead.
#if defined(_M_ARM64)
commandLine.append(LR"(" -startdir=none -arch=arm64 -host_arch=x64)");
commandLine.append(LR"(" -startdir=none -arch=arm64 -host_arch=)");
if (instance.VersionInRange(L"[17.4,"))
{
commandLine.append(LR"(arm64)");
}
else
{
commandLine.append(LR"(x64)");
}
#elif defined(_M_AMD64)
commandLine.append(LR"(" -startdir=none -arch=x64 -host_arch=x64)");
#else

View File

@ -39,17 +39,43 @@ std::wstring VsDevShellGenerator::GetProfileName(const VsSetupConfiguration::VsS
std::wstring VsDevShellGenerator::GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance& instance) const
{
// The triple-quotes are a PowerShell path escape sequence that can safely be stored in a JSON object.
// The "SkipAutomaticLocation" parameter will prevent "Enter-VsDevShell" from automatically setting the shell path
// so the path in the profile will be used instead.
// Build this in stages, so reserve space now
std::wstring commandLine;
commandLine.reserve(256);
commandLine.append(LR"(powershell.exe -NoExit -Command "&{Import-Module """)");
// Try to detect if `pwsh.exe` is available in the PATH, if so we want to use that
// Allow some extra space in case user put it somewhere odd
// We do need to allocate space for the full path even if we don't want to paste the whole thing in
wchar_t pwshPath[MAX_PATH] = { 0 };
const auto pwshExeName = L"pwsh.exe";
if (SearchPathW(nullptr, pwshExeName, nullptr, MAX_PATH, pwshPath, nullptr))
{
commandLine.append(pwshExeName);
}
else
{
commandLine.append(L"powershell.exe");
}
// The triple-quotes are a PowerShell path escape sequence that can safely be stored in a JSON object.
// The "SkipAutomaticLocation" parameter will prevent "Enter-VsDevShell" from automatically setting the shell path
// so the path in the profile will be used instead
commandLine.append(LR"( -NoExit -Command "&{Import-Module """)");
commandLine.append(GetDevShellModulePath(instance));
commandLine.append(LR"("""; Enter-VsDevShell )");
commandLine.append(instance.GetInstanceId());
#if defined(_M_ARM64)
commandLine.append(LR"( -SkipAutomaticLocation -DevCmdArguments """-arch=arm64 -host_arch=x64"""}")");
// This part stays constant no matter what
commandLine.append(LR"( -SkipAutomaticLocation -DevCmdArguments """-arch=arm64 -host_arch=)");
if (instance.VersionInRange(L"[17.4,"))
{
commandLine.append(LR"("arm64 """}")");
}
// If an old version of VS is installed without ARM64 host support
else
{
commandLine.append(LR"("x64 """}")");
}
#elif defined(_M_AMD64)
commandLine.append(LR"( -SkipAutomaticLocation -DevCmdArguments """-arch=x64 -host_arch=x64"""}")");
#else