-
Notifications
You must be signed in to change notification settings - Fork 337
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add WSL extension to Dev Home (#3365)
* add initial code for wsl * add more changes * add more changes * add more changes * add more changes * add more changes * add more changes * complete changes for wsl extension * fix build error about self-containing * Remove console write log and use serilog in packagehelper * fix launching console window when terminal not installed * update based on comments * update distribution definition helper based on comments * update based on more comments
- Loading branch information
Showing
55 changed files
with
3,052 additions
and
44 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
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
36 changes: 36 additions & 0 deletions
36
extensions/WSLExtension/ClassExtensions/IHostExtensions.cs
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,36 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
namespace WSLExtension.ClassExtensions; | ||
|
||
public static class IHostExtensions | ||
{ | ||
/// <inheritdoc cref="ActivatorUtilities.CreateInstance(IServiceProvider, Type, object[])"/> | ||
public static T CreateInstance<T>(this IHost host, params object[] parameters) | ||
{ | ||
return ActivatorUtilities.CreateInstance<T>(host.Services, parameters); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the service object for the specified type, or throws an exception | ||
/// if type was not registered. | ||
/// </summary> | ||
/// <typeparam name="T">Service type</typeparam> | ||
/// <param name="host">Host object</param> | ||
/// <returns>Service object</returns> | ||
/// <exception cref="ArgumentException">Throw an exception if the specified | ||
/// type is not registered</exception> | ||
public static T GetService<T>(this IHost host) | ||
where T : class | ||
{ | ||
if (host.Services.GetService(typeof(T)) is not T service) | ||
{ | ||
throw new ArgumentException($"{typeof(T)} needs to be registered in ConfigureServices."); | ||
} | ||
|
||
return service; | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
extensions/WSLExtension/ClassExtensions/ResourceExtensions.cs
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,13 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using Microsoft.Windows.ApplicationModel.Resources; | ||
|
||
namespace WSLExtension.ClassExtensions; | ||
|
||
public static class ResourceExtensions | ||
{ | ||
private static readonly ResourceLoader _resourceLoader = new(); | ||
|
||
public static string GetLocalized(this string resourceKey) => _resourceLoader.GetString(resourceKey); | ||
} |
34 changes: 34 additions & 0 deletions
34
extensions/WSLExtension/ClassExtensions/ServiceExtensions.cs
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,34 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Hosting; | ||
using Microsoft.Windows.DevHome.SDK; | ||
using WSLExtension.Contracts; | ||
using WSLExtension.DevHomeProviders; | ||
using WSLExtension.DistributionDefinitions; | ||
using WSLExtension.Models; | ||
using WSLExtension.Services; | ||
|
||
namespace WSLExtension.ClassExtensions; | ||
|
||
public static class ServiceExtensions | ||
{ | ||
public static IServiceCollection AddWslExtensionServices(this IServiceCollection services) | ||
{ | ||
// Services | ||
services.AddSingleton<IWslServicesMediator, WslServicesMediator>(); | ||
services.AddSingleton<IDistributionDefinitionHelper, DistributionDefinitionHelper>(); | ||
services.AddSingleton<IStringResource, StringResource>(); | ||
services.AddSingleton<IComputeSystemProvider, WslProvider>(); | ||
services.AddSingleton<WslExtension>(); | ||
services.AddSingleton<IProcessCreator, ProcessCreator>(); | ||
services.AddSingleton<IWslManager, WslManager>(); | ||
|
||
// Factory delegate to create WslComputeSystems | ||
services.AddSingleton<WslRegisteredDistributionFactory>( | ||
serviceProvider => wslDistribution => ActivatorUtilities.CreateInstance<WslComputeSystem>(serviceProvider, wslDistribution)); | ||
|
||
return services; | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
extensions/WSLExtension/ClassExtensions/StringExtensions.cs
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,14 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using System.Globalization; | ||
|
||
namespace WSLExtension.ClassExtensions; | ||
|
||
public static class StringExtensions | ||
{ | ||
public static string FormatArgs(this string source, params object[] args) | ||
{ | ||
return string.Format(CultureInfo.InvariantCulture, source, args); | ||
} | ||
} |
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,70 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
namespace WSLExtension; | ||
|
||
public static class Constants | ||
{ | ||
#if CANARY_BUILD | ||
public const string ExtensionIcon = "ms-resource://Microsoft.Windows.DevHome.Canary/Files/WslAssets/wslLinux.png"; | ||
#elif STABLE_BUILD | ||
public const string ExtensionIcon = "ms-resource://Microsoft.Windows.DevHome/Files/WslAssets/wslLinux.png"; | ||
#else | ||
public const string ExtensionIcon = "ms-resource://Microsoft.Windows.DevHome.Dev/Files/WslAssets/wslLinux.png"; | ||
#endif | ||
|
||
// Common unlocalized strings used for WSL extension | ||
public const string WslProviderDisplayName = "Microsoft WSL"; | ||
public const string WslProviderId = "Microsoft.WSL"; | ||
public const string WindowsTerminalShimExe = "wt.exe"; | ||
public const string WindowsTerminalPackageFamilyName = "Microsoft.WindowsTerminal_8wekyb3d8bbwe"; | ||
public const string WslExe = "wsl.exe"; | ||
public const string WslTemplateSubfolderName = "WslTemplates"; | ||
|
||
public const string DefaultWslLogoPath = @"ms-appx:///WslAssets/wslLinux.png"; | ||
public const string WslLogoPathFormat = @"ms-appx:///WslAssets/{0}"; | ||
public const string KnownDistributionsLocalYamlLocation = @"ms-appx:///DistributionDefinitions/DistributionDefinition.yaml"; | ||
public const string KnownDistributionsWebJsonLocation = @"https://aka.ms/wsldistributionsjson"; | ||
|
||
// Wsl registry location for registered distributions. | ||
public const string WslRegistryLocation = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Lxss"; | ||
|
||
// Wsl registry data names within a distribution location. | ||
public const string PackageFamilyRegistryName = "PackageFamilyName"; | ||
public const string DistributionRegistryName = "DistributionName"; | ||
public const string DefaultDistributionRegistryName = "DefaultDistribution"; | ||
public const string WslVersion = "Version"; | ||
public const string WslState = "State"; | ||
public const int WslVersion1 = 1; | ||
public const int WslVersion2 = 2; | ||
public const int WslExeExitSuccess = 0; | ||
|
||
// Launch terminal with specific profile and log the user into their home directory in the login shell | ||
// Note: this opens a new terminal window in the UI | ||
public static string LaunchDistributionInTerminalWithProfile { get; } = "--profile {0} -- wsl --shell-type login --cd ~ --distribution {1}"; | ||
|
||
// Launch without using a Terminal profile and log the user into their home directory using the login shell | ||
// Note: this opens a new terminal window in the UI | ||
public static string LaunchDistributionInTerminalWithNoProfile { get; } = "wsl --shell-type login --cd ~ --distribution {0}"; | ||
|
||
// Launch into the wsl process without terminal and log the user into their home directory using the login shell | ||
// Note: this opens a new terminal window in the UI | ||
public static string LaunchDistributionWithoutTerminal { get; } = "--shell-type login --cd ~ --distribution {0}"; | ||
|
||
// Arguments to unregister a wsl distribution from a machine using wsl.exe | ||
public const string UnregisterDistributionArgs = "--unregister {0}"; | ||
|
||
// Arguments to terminate all wsl sessions for a specific distribution using wsl.exe | ||
public const string TerminateDistributionArgs = "--terminate {0}"; | ||
|
||
// Arguments to download, install and register a wsl distribution using Terminal | ||
// Note: this opens a new terminal window in the UI | ||
public const string InstallDistributionWithTerminal = "wsl --install --distribution {0}"; | ||
|
||
// Arguments to download, install and register a wsl distribution without using terminal | ||
// Note: this opens a cmd window in the UI | ||
public const string InstallDistributionWithoutTerminal = "--install --distribution {0}"; | ||
|
||
// Arguments to list of all running distributions on a machine using wsl.exe | ||
public const string ListAllRunningDistributions = "--list --running"; | ||
} |
23 changes: 23 additions & 0 deletions
23
extensions/WSLExtension/Contracts/IDistributionDefinitionHelper.cs
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,23 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using WSLExtension.DistributionDefinitions; | ||
|
||
namespace WSLExtension.Contracts; | ||
|
||
/// <summary> | ||
/// Provides definition information about all the WSL distributions that can be found at | ||
/// <see cref="Constants.KnownDistributionsWebJsonLocation"/>. | ||
/// </summary> | ||
public interface IDistributionDefinitionHelper | ||
{ | ||
/// <summary> | ||
/// Retrieves a list of objects that contain metadata about WSL distributions that can be | ||
/// installed from the wsl.exe executable. | ||
/// </summary> | ||
/// <returns> | ||
/// A Dictionary where the key is the name of the distribution and the value is its | ||
/// <see cref="DistributionDefinition"/> metadata. | ||
/// </returns> | ||
public Task<Dictionary<string, DistributionDefinition>> GetDistributionDefinitionsAsync(); | ||
} |
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,32 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using WSLExtension.Models; | ||
|
||
namespace WSLExtension.Contracts; | ||
|
||
/// <summary> | ||
/// Interface used to create processes throughout the WSL extension. | ||
/// </summary> | ||
public interface IProcessCreator | ||
{ | ||
/// <summary> | ||
/// Creates and starts a new process that opens in a new Window. Note: | ||
/// The process is started and the method does not wait until the process | ||
/// has exited before returning. | ||
/// </summary> | ||
/// <param name="fileName">The name of the executable to start</param> | ||
/// <param name="arguments">The arguments that will be passed to the executable at process startup</param> | ||
public void CreateProcessWithWindow(string fileName, string arguments); | ||
|
||
/// <summary> | ||
/// Creates and starts a new process without opening a window. Note: execution is blocked | ||
/// until the process exits. | ||
/// </summary> | ||
/// <param name="fileName">The name of the executable to start</param> | ||
/// <param name="arguments">The arguments that will be passed to the executable at process startup</param> | ||
/// <returns>The meta data associated with the exited process. | ||
/// E.g StdOutput, StdError and its exit code. | ||
/// </returns> | ||
public WslProcessData CreateProcessWithoutWindowAndWaitForExit(string fileName, string arguments); | ||
} |
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,9 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
namespace WSLExtension.Contracts; | ||
|
||
public interface IStringResource | ||
{ | ||
public string GetLocalized(string key, params object[] args); | ||
} |
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,55 @@ | ||
// Copyright (c) Microsoft Corporation. | ||
// Licensed under the MIT License. | ||
|
||
using WSLExtension.DistributionDefinitions; | ||
using WSLExtension.Models; | ||
|
||
namespace WSLExtension.Contracts; | ||
|
||
/// <summary> | ||
/// Used to interact between the WSL dev environment compute systems and the WSL mediator. | ||
/// </summary> | ||
public interface IWslManager | ||
{ | ||
public event EventHandler<HashSet<string>>? DistributionStateSyncEventHandler; | ||
|
||
/// <summary> Gets a list of all registered WSL distributions on the machine.</summary> | ||
public Task<List<WslComputeSystem>> GetAllRegisteredDistributionsAsync(); | ||
|
||
/// <summary> | ||
/// Gets a list of objects that each contain metadata about a wsl distribution | ||
/// that is not currently registered on the machine and is available to install. | ||
/// </summary> | ||
public Task<List<DistributionDefinition>> GetAllDistributionsAvailableToInstallAsync(); | ||
|
||
/// <summary> | ||
/// Gets a list of objects that each contain information about a WSL distribution that is already | ||
/// registered on the machine. | ||
/// </summary> | ||
public Task<WslRegisteredDistribution?> GetInformationOnRegisteredDistributionAsync(string distributionName); | ||
|
||
/// <summary> | ||
/// Unregisters a WSL distribution. This is a wrapper for <see cref="IWslServicesMediator.UnregisterDistribution(string)"/> | ||
/// </summary> | ||
void UnregisterDistribution(string distributionName); | ||
|
||
/// <summary> Launches a new WSL distribution. | ||
/// This is a wrapper for <see cref="IWslServicesMediator.LaunchDistribution"/> | ||
/// </summary> | ||
void LaunchDistribution(string distributionName, string? windowsTerminalProfile); | ||
|
||
/// <summary> Installs a new WSL distribution. | ||
/// This is a wrapper for <see cref="IWslServicesMediator.InstallDistribution(string)"/> | ||
/// </summary> | ||
void InstallDistribution(string distributionName); | ||
|
||
/// <summary> Terminates all sessions for a new WSL distribution. | ||
/// This is a wrapper for <see cref="IWslServicesMediator.TerminateDistribution(string)"/> | ||
/// </summary> | ||
void TerminateDistribution(string distributionName); | ||
|
||
/// <summary> Gets a boolean indicating whether the WSL distribution is currently running. | ||
/// This is a wrapper for <see cref="IWslServicesMediator.IsDistributionRunning(string)"/> | ||
/// </summary> | ||
public bool IsDistributionRunning(string distributionName); | ||
} |
Oops, something went wrong.