Code to add WSLProfiles. (#1050)
* Code to add WSLProfiles. * Updates recomended by miniksa * Corrections from Mauve * More updates from miniska (clarified WaitForSingleObject errors, and moved the try block to the calling function) * Added THROW_LAST_ERROR for WAIT_FAILED instead of passing an unhandled exception. * Migrate STL dependancies to LibraryIncludes.h * Renamed function to provide more clarity * Set WSL starting directory. * Default Linux icon and brackets on new lines. * Added system path so we don't rely on execution from the PATH environment variable. Removed incorrect error useage. Removed variable that was not required. * Remove default directory setting.
This commit is contained in:
parent
6b51d783c2
commit
31b614d5b2
|
@ -4,6 +4,8 @@
|
|||
#include "pch.h"
|
||||
#include <argb.h>
|
||||
#include <conattrs.hpp>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include "CascadiaSettings.h"
|
||||
#include "../../types/inc/utils.hpp"
|
||||
#include "../../inc/DefaultSettings.h"
|
||||
|
@ -21,6 +23,7 @@ static constexpr GUID TERMINAL_PROFILE_NAMESPACE_GUID =
|
|||
|
||||
static constexpr std::wstring_view PACKAGED_PROFILE_ICON_PATH{ L"ms-appx:///ProfileIcons/" };
|
||||
static constexpr std::wstring_view PACKAGED_PROFILE_ICON_EXTENSION{ L".png" };
|
||||
static constexpr std::wstring_view DEFAULT_LINUX_ICON_GUID{ L"{9acb9455-ca41-5af7-950f-6bca1bc9722f}" };
|
||||
|
||||
CascadiaSettings::CascadiaSettings() :
|
||||
_globals{},
|
||||
|
@ -227,6 +230,11 @@ void CascadiaSettings::_CreateDefaultProfiles()
|
|||
|
||||
_profiles.emplace_back(powershellProfile);
|
||||
_profiles.emplace_back(cmdProfile);
|
||||
try
|
||||
{
|
||||
_AppendWslProfiles(_profiles);
|
||||
}
|
||||
CATCH_LOG()
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
@ -467,6 +475,78 @@ bool CascadiaSettings::_isPowerShellCoreInstalledInPath(const std::wstring_view
|
|||
return false;
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Adds all of the WSL profiles to the provided container.
|
||||
// Arguments:
|
||||
// - A ref to the profiles container where the WSL profiles are to be added
|
||||
// Return Value:
|
||||
// - <none>
|
||||
void CascadiaSettings::_AppendWslProfiles(std::vector<TerminalApp::Profile>& profileStorage)
|
||||
{
|
||||
wil::unique_handle readPipe;
|
||||
wil::unique_handle writePipe;
|
||||
SECURITY_ATTRIBUTES sa{ sizeof(sa), nullptr, true };
|
||||
THROW_IF_WIN32_BOOL_FALSE(CreatePipe(&readPipe, &writePipe, &sa, 0));
|
||||
STARTUPINFO si{};
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdOutput = writePipe.get();
|
||||
si.hStdError = writePipe.get();
|
||||
wil::unique_process_information pi{};
|
||||
wil::unique_cotaskmem_string systemPath;
|
||||
THROW_IF_FAILED(wil::GetSystemDirectoryW(systemPath));
|
||||
std::wstring command(systemPath.get());
|
||||
command += L"\\wsl.exe --list";
|
||||
|
||||
THROW_IF_WIN32_BOOL_FALSE(CreateProcessW(nullptr, const_cast<LPWSTR>(command.c_str()), nullptr, nullptr,
|
||||
TRUE, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi));
|
||||
switch (WaitForSingleObject(pi.hProcess, INFINITE))
|
||||
{
|
||||
case WAIT_OBJECT_0:
|
||||
break;
|
||||
case WAIT_ABANDONED:
|
||||
case WAIT_TIMEOUT:
|
||||
THROW_HR(ERROR_CHILD_NOT_COMPLETE);
|
||||
case WAIT_FAILED:
|
||||
THROW_LAST_ERROR();
|
||||
default:
|
||||
THROW_HR(ERROR_UNHANDLED_EXCEPTION);
|
||||
}
|
||||
DWORD exitCode;
|
||||
if (GetExitCodeProcess(pi.hProcess, &exitCode) == false)
|
||||
{
|
||||
THROW_HR(E_INVALIDARG);
|
||||
}
|
||||
else if (exitCode != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
DWORD bytesAvailable;
|
||||
THROW_IF_WIN32_BOOL_FALSE(PeekNamedPipe(readPipe.get(), nullptr, NULL, nullptr, &bytesAvailable, nullptr));
|
||||
std::wfstream pipe{ _wfdopen(_open_osfhandle((intptr_t)readPipe.get(), _O_WTEXT | _O_RDONLY), L"r") };
|
||||
//don't worry about the handle returned from wfdOpen, readPipe handle is already managed by wil and closing the file handle will cause an error.
|
||||
std::wstring wline;
|
||||
std::getline(pipe, wline); //remove the header from the output.
|
||||
while (pipe.tellp() < bytesAvailable)
|
||||
{
|
||||
std::getline(pipe, wline);
|
||||
std::wstringstream wlinestream(wline);
|
||||
if (wlinestream)
|
||||
{
|
||||
std::wstring distName;
|
||||
std::getline(wlinestream, distName, L' ');
|
||||
auto WSLDistro{ _CreateDefaultProfile(distName) };
|
||||
WSLDistro.SetCommandline(L"wsl.exe -d " + distName);
|
||||
WSLDistro.SetColorScheme({ L"Campbell" });
|
||||
std::wstring iconPath{ PACKAGED_PROFILE_ICON_PATH };
|
||||
iconPath.append(DEFAULT_LINUX_ICON_GUID);
|
||||
iconPath.append(PACKAGED_PROFILE_ICON_EXTENSION);
|
||||
WSLDistro.SetIconPath(iconPath);
|
||||
profileStorage.emplace_back(WSLDistro);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
// - Get a environment variable string.
|
||||
// Arguments:
|
||||
|
|
|
@ -70,6 +70,7 @@ private:
|
|||
static std::optional<std::string> _LoadAsUnpackagedApp();
|
||||
static bool _isPowerShellCoreInstalledInPath(const std::wstring_view programFileEnv, std::filesystem::path& cmdline);
|
||||
static bool _isPowerShellCoreInstalled(std::filesystem::path& cmdline);
|
||||
static void _AppendWslProfiles(std::vector<TerminalApp::Profile>& profileStorage);
|
||||
static std::wstring ExpandEnvironmentVariableString(std::wstring_view source);
|
||||
static Profile _CreateDefaultProfile(const std::wstring_view name);
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include <iterator>
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
|
|
Loading…
Reference in a new issue