-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add profile generators for Visual Studio (#7774)
This commit adds dynamic profile generators for Visual Studio Developer Command Prompt (VS2017+) and Visual Studio Developer PowerShell (VS2019.2+) Tested manually by deploying locally. My local environment has four instances of VS installed, one VS2017 and multiple channels of VS2019. We're wrapping the COM Visual Studio Setup Configuration API to query for VS instances and retrieve the relevant properties. Two different namespaces are used so the end-user can turn off one or the other. For instance, end user may prefer to always use Developer PowerShell. ## Validation Steps Performed 1. Build locally using Visual Studio 2019 2. Deploy CascadiaPackage 3. Verify entries exist in profiles menu 4. Verify entries exist in settings.json 5. Open each profile 6. Validate start-in directory 7. Validate environment variables are as expected 8. Uninstall Windows Terminal - Dev package 9. Repeat. Closes #3821
- Loading branch information
Showing
15 changed files
with
643 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -66,6 +66,7 @@ iosfwd | |
IPackage | ||
IPeasant | ||
isspace | ||
ISetup | ||
IStorage | ||
istream | ||
IStringable | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2578,6 +2578,7 @@ VREDRAW | |
vsc | ||
vscprintf | ||
VSCROLL | ||
vsdevshell | ||
vsinfo | ||
vsnprintf | ||
vso | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
src/cascadia/TerminalSettingsModel/BaseVisualStudioGenerator.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
#include "pch.h" | ||
#include "BaseVisualStudioGenerator.h" | ||
#include "DefaultProfileUtils.h" | ||
|
||
using namespace Microsoft::Terminal::Settings::Model; | ||
using namespace winrt::Microsoft::Terminal::Settings::Model; | ||
|
||
std::vector<Profile> BaseVisualStudioGenerator::GenerateProfiles() | ||
{ | ||
std::vector<Profile> profiles; | ||
|
||
// There's no point in enumerating valid Visual Studio instances more than once, | ||
// so cache them for use by both Visual Studio profile generators. | ||
if (!BaseVisualStudioGenerator::hasQueried) | ||
{ | ||
instances = VsSetupConfiguration::QueryInstances(); | ||
hasQueried = true; | ||
} | ||
|
||
for (auto const& instance : BaseVisualStudioGenerator::instances) | ||
{ | ||
try | ||
{ | ||
if (!IsInstanceValid(instance)) | ||
continue; | ||
|
||
auto DevShell{ CreateProfile(GetProfileGuidSeed(instance)) }; | ||
DevShell.Name(GetProfileName(instance)); | ||
DevShell.Commandline(GetProfileCommandLine(instance)); | ||
DevShell.StartingDirectory(instance.GetInstallationPath()); | ||
DevShell.Icon(GetProfileIconPath()); | ||
|
||
profiles.emplace_back(DevShell); | ||
} | ||
CATCH_LOG(); | ||
} | ||
|
||
return profiles; | ||
} | ||
|
||
Profile BaseVisualStudioGenerator::CreateProfile(const std::wstring_view seed) | ||
{ | ||
const winrt::guid profileGuid{ Microsoft::Console::Utils::CreateV5Uuid(TERMINAL_PROFILE_NAMESPACE_GUID, | ||
gsl::as_bytes(gsl::make_span(seed))) }; | ||
|
||
auto newProfile = winrt::make_self<implementation::Profile>(profileGuid); | ||
newProfile->Origin(OriginTag::Generated); | ||
|
||
return *newProfile; | ||
} |
41 changes: 41 additions & 0 deletions
41
src/cascadia/TerminalSettingsModel/BaseVisualStudioGenerator.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
/*++ | ||
Copyright (c) Microsoft Corporation | ||
Licensed under the MIT license. | ||
Module Name: | ||
- BaseVisualStudioGenerator | ||
Abstract: | ||
- Base generator for Visual Studio Developer shell profiles | ||
Author(s): | ||
- Charles Willis - October 2020 | ||
--*/ | ||
|
||
#pragma once | ||
|
||
#include "IDynamicProfileGenerator.h" | ||
#include "VsSetupConfiguration.h" | ||
|
||
namespace Microsoft::Terminal::Settings::Model | ||
{ | ||
class BaseVisualStudioGenerator : public IDynamicProfileGenerator | ||
{ | ||
virtual bool IsInstanceValid(const VsSetupConfiguration::VsSetupInstance instance) const = 0; | ||
virtual std::wstring GetProfileName(const VsSetupConfiguration::VsSetupInstance instance) const = 0; | ||
virtual std::wstring GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance instance) const = 0; | ||
virtual std::wstring GetProfileGuidSeed(const VsSetupConfiguration::VsSetupInstance instance) const = 0; | ||
virtual std::wstring GetProfileIconPath() const = 0; | ||
|
||
// Inherited via IDynamicProfileGenerator | ||
virtual std::wstring_view GetNamespace() override = 0; | ||
std::vector<winrt::Microsoft::Terminal::Settings::Model::Profile> GenerateProfiles() override; | ||
|
||
private: | ||
inline static bool hasQueried = false; | ||
inline static std::vector<VsSetupConfiguration::VsSetupInstance> instances; | ||
|
||
winrt::Microsoft::Terminal::Settings::Model::Profile CreateProfile(const std::wstring_view instanceId); | ||
}; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
#include "pch.h" | ||
#include "VsDevCmdGenerator.h" | ||
|
||
using namespace Microsoft::Terminal::Settings::Model; | ||
|
||
std::wstring VsDevCmdGenerator::GetProfileName(const VsSetupConfiguration::VsSetupInstance instance) const | ||
{ | ||
std::wstring name{ L"Developer Command Prompt for VS " }; | ||
name.append(instance.GetProfileNameSuffix()); | ||
return name; | ||
} | ||
|
||
std::wstring VsDevCmdGenerator::GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance instance) const | ||
{ | ||
std::wstring commandLine{ L"cmd.exe /k \"" + instance.GetDevCmdScriptPath() + L"\"" }; | ||
|
||
return commandLine; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/*++ | ||
Copyright (c) Microsoft Corporation | ||
Licensed under the MIT license. | ||
Module Name: | ||
- VsDevCmdGenerator | ||
Abstract: | ||
- Dynamic profile generator for Visual Studio Developer Command Prompt | ||
Author(s): | ||
- Charles Willis - October 2020 | ||
--*/ | ||
|
||
#pragma once | ||
#include "BaseVisualStudioGenerator.h" | ||
|
||
namespace Microsoft::Terminal::Settings::Model | ||
{ | ||
class VsDevCmdGenerator : public BaseVisualStudioGenerator | ||
{ | ||
public: | ||
VsDevCmdGenerator() = default; | ||
~VsDevCmdGenerator() = default; | ||
|
||
std::wstring_view GetNamespace() override | ||
{ | ||
return std::wstring_view{ L"Windows.Terminal.VisualStudio.CommandPrompt" }; | ||
} | ||
|
||
inline bool IsInstanceValid(const VsSetupConfiguration::VsSetupInstance instance) const override | ||
{ | ||
// We only support version of VS from 15.0. | ||
// Per heaths: The [ISetupConfiguration] COM server only supports Visual Studio 15.0 and newer anyway. | ||
// Eliding the version range will improve the discovery performance by not having to parse or compare the versions. | ||
return true; | ||
} | ||
|
||
inline std::wstring GetProfileGuidSeed(const VsSetupConfiguration::VsSetupInstance instance) const override | ||
{ | ||
return L"VsDevCmd" + instance.GetInstanceId(); | ||
} | ||
|
||
inline std::wstring GetProfileIconPath() const override | ||
{ | ||
return L"ms-appx:///ProfileIcons/{0caa0dad-35be-5f56-a8ff-afceeeaa6101}.png"; | ||
} | ||
|
||
std::wstring GetProfileName(const VsSetupConfiguration::VsSetupInstance instance) const override; | ||
std::wstring GetProfileCommandLine(const VsSetupConfiguration::VsSetupInstance instance) const override; | ||
}; | ||
}; |
30 changes: 30 additions & 0 deletions
30
src/cascadia/TerminalSettingsModel/VsDevShellGenerator.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT license. | ||
|
||
#include "pch.h" | ||
#include "VsDevShellGenerator.h" | ||
#include "Setup.Configuration.h" | ||
#include "DefaultProfileUtils.h" | ||
#include "VsSetupConfiguration.h" | ||
|
||
using namespace Microsoft::Terminal::Settings::Model; | ||
|
||
std::wstring VsDevShellGenerator::GetProfileName(const VsSetupConfiguration::VsSetupInstance instance) const | ||
{ | ||
std::wstring name{ L"Developer PowerShell for VS " }; | ||
name.append(instance.GetProfileNameSuffix()); | ||
return name; | ||
} | ||
|
||
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. | ||
std::wstring commandLine{ L"powershell.exe -NoExit -Command \"& {" }; | ||
commandLine.append(L"Import-Module \"\"\"" + instance.GetDevShellModulePath() + L"\"\"\";"); | ||
commandLine.append(L"Enter-VsDevShell " + instance.GetInstanceId() + L" -SkipAutomaticLocation"); | ||
commandLine.append(L"}\""); | ||
|
||
return commandLine; | ||
} |
Oops, something went wrong.