├── .gitignore ├── LICENSE ├── PRIVACY ├── README.md ├── assets ├── img │ └── easyWSL-Logo.png └── vid │ ├── configureDistro.mp4 │ ├── getDistro.mp4 │ ├── manageDistro.mp4 │ ├── settingsPage.mp4 │ └── snapshots.mp4 ├── easyWSL.sln ├── easyWSL ├── AboutDialog.xaml ├── AboutDialog.xaml.cs ├── App.xaml ├── App.xaml.cs ├── Assets │ ├── BadgeLogo.scale-100.png │ ├── BadgeLogo.scale-125.png │ ├── BadgeLogo.scale-150.png │ ├── BadgeLogo.scale-200.png │ ├── BadgeLogo.scale-400.png │ ├── LargeTile.scale-100.png │ ├── LargeTile.scale-125.png │ ├── LargeTile.scale-150.png │ ├── LargeTile.scale-200.png │ ├── LargeTile.scale-400.png │ ├── LockScreenLogo.scale-200.png │ ├── SmallTile.scale-100.png │ ├── SmallTile.scale-125.png │ ├── SmallTile.scale-150.png │ ├── SmallTile.scale-200.png │ ├── SmallTile.scale-400.png │ ├── SplashScreen.scale-100.png │ ├── SplashScreen.scale-125.png │ ├── SplashScreen.scale-150.png │ ├── SplashScreen.scale-200.png │ ├── SplashScreen.scale-400.png │ ├── Square150x150Logo.scale-100.png │ ├── Square150x150Logo.scale-125.png │ ├── Square150x150Logo.scale-150.png │ ├── Square150x150Logo.scale-200.png │ ├── Square150x150Logo.scale-400.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-16.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-24.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-256.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-32.png │ ├── Square44x44Logo.altform-lightunplated_targetsize-48.png │ ├── Square44x44Logo.altform-unplated_targetsize-16.png │ ├── Square44x44Logo.altform-unplated_targetsize-256.png │ ├── Square44x44Logo.altform-unplated_targetsize-32.png │ ├── Square44x44Logo.altform-unplated_targetsize-48.png │ ├── Square44x44Logo.scale-100.png │ ├── Square44x44Logo.scale-125.png │ ├── Square44x44Logo.scale-150.png │ ├── Square44x44Logo.scale-200.png │ ├── Square44x44Logo.scale-400.png │ ├── Square44x44Logo.targetsize-16.png │ ├── Square44x44Logo.targetsize-24.png │ ├── Square44x44Logo.targetsize-24_altform-unplated.png │ ├── Square44x44Logo.targetsize-256.png │ ├── Square44x44Logo.targetsize-32.png │ ├── Square44x44Logo.targetsize-48.png │ ├── StoreLogo.backup.png │ ├── StoreLogo.scale-100.png │ ├── StoreLogo.scale-125.png │ ├── StoreLogo.scale-150.png │ ├── StoreLogo.scale-200.png │ ├── StoreLogo.scale-400.png │ ├── Wide310x150Logo.scale-100.png │ ├── Wide310x150Logo.scale-125.png │ ├── Wide310x150Logo.scale-150.png │ ├── Wide310x150Logo.scale-200.png │ └── Wide310x150Logo.scale-400.png ├── ManageDistrosPage.xaml ├── ManageDistrosPage.xaml.cs ├── ManageSnapshotsPage.xaml ├── ManageSnapshotsPage.xaml.cs ├── MoreInfoDialog.xaml ├── MoreInfoDialog.xaml.cs ├── NavigationRoot_Window.xaml ├── NavigationRoot_Window.xaml.cs ├── Package.appxmanifest ├── PlatformHelpers.cs ├── Properties │ └── launchSettings.json ├── RegisterNewDistro_Page.xaml ├── RegisterNewDistro_Page.xaml.cs ├── SettingsPage.xaml ├── SettingsPage.xaml.cs ├── WelcomeWindow.xaml ├── WelcomeWindow.xaml.cs ├── WslSdk.cs ├── app.manifest ├── dep │ ├── WindowsHelloBridge.exe │ ├── bsdtar.exe │ ├── bzip2.dll │ ├── libarchive2.dll │ ├── pam_wsl_hello.so │ └── zlib1.dll ├── easyWSL.csproj └── easyWSL.ico ├── easyWSLcmd ├── PlatformHelpers.cs ├── Program.cs ├── Properties │ └── launchSettings.json └── easyWSLcmd.csproj └── easyWslLib ├── DockerDownloader.cs ├── Helpers.cs ├── IPlatformHelpers.cs └── easyWslLib.csproj /.gitignore: -------------------------------------------------------------------------------- 1 | .vs/ 2 | bin/ 3 | obj/ 4 | easyWSL/easyWSL.csproj.user 5 | easyWSL/Package.StoreAssociation.xml -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # easyWSL 2 | 3 | Copyright (c) 2020 RedCode-Labs and Jakub Wróbel 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | 11 | # bsdtar 12 | 13 | All of the C source code and documentation in this package is subject 14 | to the following: 15 | 16 | Copyright (c) 2003-2006 Tim Kientzle 17 | All rights reserved. 18 | 19 | Redistribution and use in source and binary forms, with or without 20 | modification, are permitted provided that the following conditions 21 | are met: 22 | 1. Redistributions of source code must retain the above copyright 23 | notice, this list of conditions and the following disclaimer 24 | in this position and unchanged. 25 | 2. Redistributions in binary form must reproduce the above copyright 26 | notice, this list of conditions and the following disclaimer in the 27 | documentation and/or other materials provided with the distribution. 28 | 29 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 30 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 31 | OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 32 | IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 33 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 34 | NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 38 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 | 40 | # WSL-Hello-sudo 41 | 42 | Copyright 2017 Takaya Saeki 43 | 44 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 45 | 46 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 47 | 48 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 49 | -------------------------------------------------------------------------------- /PRIVACY: -------------------------------------------------------------------------------- 1 | We don't collect any data. 2 | Your data is yours, not ours. 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

easyWSL


2 |

3 | 4 | 5 | 6 |

7 | 8 |

9 | Create WSL distros based on Docker Images. 10 |

11 | 12 | > Made with ❤ by @redcode-labs team. 13 | 14 | ## What does this project do? 15 | 16 | easyWSL makes it way easier to use the wonders of WSL functionality on Windows 10 and 11 systems. Thanks to our efforts, easyWSL grants you an access to use most (almost all) system images from Docker Hub as WSL distros. Our C# sorcery allows us to use Docker Hub API in order to get .tar or .tar.gz images from there. After getting an image, single or multi-layered, we turn it into single image (multi-layered Docker image case) which we easily import as WSL distro. 17 | 18 | https://user-images.githubusercontent.com/40501814/161391038-10bf9360-429d-4a47-887f-63b35fae90cd.mp4 19 | 20 | ## Features 21 | 22 | In our latest release, we've added even more features than ever before. All of them wrapped around GUI app using a beauty of WinUI framework. 23 | 24 | We've managed to add management features to WSL. With a single click, you can unregister, open .vhdx location as well as see the filesystem of the given distro. 25 | 26 | https://user-images.githubusercontent.com/40501814/161391082-101aeaa4-48e1-4cc6-bac3-9bc251efe469.mp4 27 | 28 | While this sounds so good so far, we've also made a separate 'Settings' page, to manage your WSL in general. There you can easily adjust things like memory, the number of cores or the swap size assigned with WSL VM. You can also point to different swap file, custom Linux kernel and provide it with custom command line arguments. The given page has also a number of switches, with which you can manage things like localhost forwarding, page reporing, GUI applications (WSLg) support, debug console, nested virtualization. Don't worry if you get lost - you can always just 'Revert to defaults'. 29 | 30 | We've added a functionality to register currently or previously used WSL distros using their .vhdx file. Going further down the rabbit hole, we've turned it into more advanced feature - easyWSL can now make snapshots, which can easily be used as a backups/restore points for your distros. 31 | 32 | https://user-images.githubusercontent.com/40501814/161391108-42a4e891-99da-4d36-a49d-3960dff28410.mp4 33 | 34 | We've added several experimental features as well. One of them, is creating a new user at the time of installing a distro. You now can set the username and password, and, if you want to, use experimental integration of [WSL-Hello-sudo](https://github.com/nullpo-head/WSL-Hello-sudo). 35 | 36 | Furthermore, you can use an experimental feature to install development environments during the install process. This includes environments such as Python, Node.js, C/C++ and more. Not to mention, that it works cross-distro and more can be added along the way. 37 | 38 | https://user-images.githubusercontent.com/40501814/161391121-e76dc012-b819-434b-acb2-0d2696862911.mp4 39 | 40 | ## How to get it? 41 | 42 | Just go to our Microsoft Store page, which you can find [here](https://www.microsoft.com/store/apps/9NHBTMKS47RB). 43 | Get it, install, and voilà! 44 | 45 | ## Building on your own 46 | 47 | ### Prerequisites 48 | 49 | * Windows 10 1607 or later (for WSL1) or Windows 10 1903 (18362) or later 50 | * Note: you might want to check instructions on how to enable WSL [here](https://docs.microsoft.com/en-us/windows/wsl/install-manual) 51 | * [Developer Mode enabled](https://docs.microsoft.com/windows/uwp/get-started/enable-your-device-for-development) 52 | * [Visual Studio 2022](https://visualstudio.microsoft.com/downloads/) (recommended by Microsoft) 53 | * The following workloads: 54 | * .NET Desktop Development 55 | * Individual components: 56 | * Windows 10 SDK (10.0.19041.0) 57 | * The following extensions: 58 | * [System.Text.Json](https://www.nuget.org/packages/System.Text.Json/5.0.2?_src=template) 59 | 60 | More detailed info, including building on older releases of Visual Studio, can be found 61 | [here](https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/set-up-your-development-environment?tabs=vs-2022-17-1-a%2Cvs-2022-17-1-b) 62 | 63 | (Upon opening the repo in Visual Studio, it will prompt you to install any missing workloads and features.) 64 | 65 | ### Building 66 | 67 | We currently only build using the solution; command line methods of building a VS solution should work as well. 68 | 69 | ## Future plans 70 | 71 | ### CLI 72 | 73 | We are looking forward to make a CLI compatible with all of our latest features, in order to make our tool usable in scripts. 74 | 75 | If you're looking into using easyWSL as a CLI, the only current option is to use the older version (easyWSL 1.2), which you can get from the release page [here](https://github.com/redcode-labs/easyWSL/releases/tag/1.2). 76 | -------------------------------------------------------------------------------- /assets/img/easyWSL-Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/assets/img/easyWSL-Logo.png -------------------------------------------------------------------------------- /assets/vid/configureDistro.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/assets/vid/configureDistro.mp4 -------------------------------------------------------------------------------- /assets/vid/getDistro.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/assets/vid/getDistro.mp4 -------------------------------------------------------------------------------- /assets/vid/manageDistro.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/assets/vid/manageDistro.mp4 -------------------------------------------------------------------------------- /assets/vid/settingsPage.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/assets/vid/settingsPage.mp4 -------------------------------------------------------------------------------- /assets/vid/snapshots.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/assets/vid/snapshots.mp4 -------------------------------------------------------------------------------- /easyWSL.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.32112.339 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "easyWSL", "easyWSL\easyWSL.csproj", "{B6C34736-A384-44BB-A43B-2F54EC32E175}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "easyWslCmd", "easyWSLcmd\easyWslCmd.csproj", "{350F963D-AD6E-4883-8405-F99D9770A9BB}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "easyWslLib", "easyWslLib\easyWslLib.csproj", "{206BBF4A-1D8B-4CD4-9519-2633D5AB2562}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Debug|arm64 = Debug|arm64 16 | Debug|x64 = Debug|x64 17 | Debug|x86 = Debug|x86 18 | Release|Any CPU = Release|Any CPU 19 | Release|arm64 = Release|arm64 20 | Release|x64 = Release|x64 21 | Release|x86 = Release|x86 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|Any CPU.ActiveCfg = Debug|x64 25 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|Any CPU.Build.0 = Debug|x64 26 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|Any CPU.Deploy.0 = Debug|x64 27 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|arm64.ActiveCfg = Debug|arm64 28 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|arm64.Build.0 = Debug|arm64 29 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|arm64.Deploy.0 = Debug|arm64 30 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|x64.ActiveCfg = Debug|x64 31 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|x64.Build.0 = Debug|x64 32 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|x64.Deploy.0 = Debug|x64 33 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|x86.ActiveCfg = Debug|x86 34 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|x86.Build.0 = Debug|x86 35 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Debug|x86.Deploy.0 = Debug|x86 36 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|Any CPU.ActiveCfg = Release|x64 37 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|Any CPU.Build.0 = Release|x64 38 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|Any CPU.Deploy.0 = Release|x64 39 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|arm64.ActiveCfg = Release|arm64 40 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|arm64.Build.0 = Release|arm64 41 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|arm64.Deploy.0 = Release|arm64 42 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|x64.ActiveCfg = Release|x64 43 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|x64.Build.0 = Release|x64 44 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|x64.Deploy.0 = Release|x64 45 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|x86.ActiveCfg = Release|x86 46 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|x86.Build.0 = Release|x86 47 | {B6C34736-A384-44BB-A43B-2F54EC32E175}.Release|x86.Deploy.0 = Release|x86 48 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|arm64.ActiveCfg = Debug|Any CPU 51 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|arm64.Build.0 = Debug|Any CPU 52 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|x64.ActiveCfg = Debug|Any CPU 53 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|x64.Build.0 = Debug|Any CPU 54 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|x86.ActiveCfg = Debug|Any CPU 55 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Debug|x86.Build.0 = Debug|Any CPU 56 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|Any CPU.ActiveCfg = Release|Any CPU 57 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|Any CPU.Build.0 = Release|Any CPU 58 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|arm64.ActiveCfg = Release|Any CPU 59 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|arm64.Build.0 = Release|Any CPU 60 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|x64.ActiveCfg = Release|Any CPU 61 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|x64.Build.0 = Release|Any CPU 62 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|x86.ActiveCfg = Release|Any CPU 63 | {350F963D-AD6E-4883-8405-F99D9770A9BB}.Release|x86.Build.0 = Release|Any CPU 64 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|arm64.ActiveCfg = Debug|Any CPU 67 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|arm64.Build.0 = Debug|Any CPU 68 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|x64.ActiveCfg = Debug|Any CPU 69 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|x64.Build.0 = Debug|Any CPU 70 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|x86.ActiveCfg = Debug|Any CPU 71 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Debug|x86.Build.0 = Debug|Any CPU 72 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|Any CPU.ActiveCfg = Release|Any CPU 73 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|Any CPU.Build.0 = Release|Any CPU 74 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|arm64.ActiveCfg = Release|Any CPU 75 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|arm64.Build.0 = Release|Any CPU 76 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|x64.ActiveCfg = Release|Any CPU 77 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|x64.Build.0 = Release|Any CPU 78 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|x86.ActiveCfg = Release|Any CPU 79 | {206BBF4A-1D8B-4CD4-9519-2633D5AB2562}.Release|x86.Build.0 = Release|Any CPU 80 | EndGlobalSection 81 | GlobalSection(SolutionProperties) = preSolution 82 | HideSolutionNode = FALSE 83 | EndGlobalSection 84 | GlobalSection(ExtensibilityGlobals) = postSolution 85 | SolutionGuid = {831ABB30-ED12-4897-8B12-322E2CB11E55} 86 | EndGlobalSection 87 | EndGlobal 88 | -------------------------------------------------------------------------------- /easyWSL/AboutDialog.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | EasyWSL 12 | 13 | WSL made easy. Create Linux distributions, manage them and make snapshots on Windows 10/11. 14 | Made by 15 | Red Code Labs 16 | 17 | 18 | 19 | Resources used 20 | 21 | libarchive 22 | 23 | 24 | 25 | WSL Hello sudo 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /easyWSL/AboutDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml.Controls; 2 | 3 | namespace easyWSL 4 | { 5 | public sealed partial class AboutDialog : Page 6 | { 7 | public AboutDialog() 8 | { 9 | this.InitializeComponent(); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /easyWSL/App.xaml: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | Black 14 | Black 15 | White 16 | White 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /easyWSL/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml; 2 | using System; 3 | using PInvoke; 4 | using Windows.Web.Http; 5 | using System.Reflection; 6 | 7 | namespace easyWSL 8 | { 9 | public partial class App : Application 10 | { 11 | public App() 12 | { 13 | this.InitializeComponent(); 14 | } 15 | 16 | IntPtr m_windowhandle; 17 | public IntPtr MainWindowWindowHandle { get { return m_windowhandle; } } 18 | 19 | protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) 20 | { 21 | var isWSLInstalled = WslSdk.CheckIfWSLInstalled(); 22 | if (!isWSLInstalled) 23 | { 24 | m_window = new WelcomeWindow(); 25 | } 26 | else 27 | { 28 | m_window = new NavigationRoot_Window(); 29 | } 30 | 31 | m_window.Activate(); 32 | m_window.Title = "easyWSL"; 33 | m_windowhandle = User32.GetActiveWindow(); 34 | User32.ShowWindow(m_windowhandle, User32.WindowShowStyle.SW_MAXIMIZE); 35 | } 36 | 37 | private Window m_window; 38 | 39 | public static readonly HttpClient httpClient = new(); 40 | 41 | public static string executableLocation = Assembly.GetExecutingAssembly().Location.Substring(0, Assembly.GetExecutingAssembly().Location.LastIndexOf(@"\")); 42 | public static Windows.Storage.StorageFolder tmpDirectory = Windows.Storage.ApplicationData.Current.TemporaryFolder; 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /easyWSL/Assets/BadgeLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/BadgeLogo.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/BadgeLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/BadgeLogo.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/BadgeLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/BadgeLogo.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/BadgeLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/BadgeLogo.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/BadgeLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/BadgeLogo.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/LargeTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/LargeTile.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/LargeTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/LargeTile.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/LargeTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/LargeTile.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/LargeTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/LargeTile.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/LargeTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/LargeTile.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/LockScreenLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/LockScreenLogo.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/SmallTile.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SmallTile.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/SmallTile.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SmallTile.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/SmallTile.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SmallTile.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/SmallTile.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SmallTile.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/SmallTile.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SmallTile.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/SplashScreen.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SplashScreen.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/SplashScreen.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SplashScreen.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/SplashScreen.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SplashScreen.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/SplashScreen.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SplashScreen.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/SplashScreen.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/SplashScreen.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square150x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square150x150Logo.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square150x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square150x150Logo.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square150x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square150x150Logo.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square150x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square150x150Logo.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square150x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square150x150Logo.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-16.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-24.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-256.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-32.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-lightunplated_targetsize-48.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-16.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-256.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-32.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.altform-unplated_targetsize-48.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.targetsize-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.targetsize-16.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.targetsize-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.targetsize-24.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.targetsize-24_altform-unplated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.targetsize-24_altform-unplated.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.targetsize-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.targetsize-256.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.targetsize-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.targetsize-32.png -------------------------------------------------------------------------------- /easyWSL/Assets/Square44x44Logo.targetsize-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Square44x44Logo.targetsize-48.png -------------------------------------------------------------------------------- /easyWSL/Assets/StoreLogo.backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/StoreLogo.backup.png -------------------------------------------------------------------------------- /easyWSL/Assets/StoreLogo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/StoreLogo.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/StoreLogo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/StoreLogo.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/StoreLogo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/StoreLogo.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/StoreLogo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/StoreLogo.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/StoreLogo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/StoreLogo.scale-400.png -------------------------------------------------------------------------------- /easyWSL/Assets/Wide310x150Logo.scale-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Wide310x150Logo.scale-100.png -------------------------------------------------------------------------------- /easyWSL/Assets/Wide310x150Logo.scale-125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Wide310x150Logo.scale-125.png -------------------------------------------------------------------------------- /easyWSL/Assets/Wide310x150Logo.scale-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Wide310x150Logo.scale-150.png -------------------------------------------------------------------------------- /easyWSL/Assets/Wide310x150Logo.scale-200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Wide310x150Logo.scale-200.png -------------------------------------------------------------------------------- /easyWSL/Assets/Wide310x150Logo.scale-400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/redcode-labs/easyWSL/a2835df30929f0eef2d60c762d8ef767f849ff5a/easyWSL/Assets/Wide310x150Logo.scale-400.png -------------------------------------------------------------------------------- /easyWSL/ManageDistrosPage.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | All your data stored on this distribution will be gone. 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /easyWSL/ManageDistrosPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml; 2 | using Microsoft.UI.Xaml.Controls; 3 | using System; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Threading.Tasks; 7 | using easyWslLib; 8 | 9 | namespace easyWSL 10 | { 11 | public sealed partial class ManageDistrosPage : Page 12 | { 13 | public class EditedDistro 14 | { 15 | public string name { get; set; } 16 | public string version { get; set; } 17 | public string path { get; set; } 18 | } 19 | 20 | private Windows.Storage.StorageFolder storageDirectory = Windows.Storage.ApplicationData.Current.LocalFolder; 21 | 22 | 23 | public ManageDistrosPage() 24 | { 25 | InitializeComponent(); 26 | RefreshInstalledDistros(); 27 | } 28 | 29 | private WslSdk wslSdk = new(); 30 | private Helpers helpers = new(); 31 | private ManageSnapshotsPage manageSnapshotsPage = new(); 32 | public string selectedDistroName; 33 | 34 | private async Task RefreshInstalledDistros() 35 | { 36 | await WslSdk.GetInstalledDistributions(); 37 | distrosListView.ItemsSource = null; 38 | distrosListView.Items.Clear(); 39 | distrosListView.ItemsSource = WslSdk.InstalledDistros.Values; 40 | if(distrosListView.Items.Count != 0) 41 | { 42 | distrosListView.SelectedIndex = 0; 43 | } 44 | 45 | } 46 | private void distrosListView_SelectionChanged(object sender, SelectionChangedEventArgs e) 47 | { 48 | if (e.AddedItems.Count == 1) 49 | { 50 | selectedDistroName = distrosListView.SelectedValue.ToString(); 51 | } 52 | } 53 | private async void removeDistroButton_Click(object sender, RoutedEventArgs e) 54 | { 55 | confirmDistroRemovalDialog.Title = $"Are you sure you want to remove {selectedDistroName}?"; 56 | confirmDistroRemovalDialog.XamlRoot = removeDistroButton.XamlRoot; 57 | ContentDialogResult dialogResult = await confirmDistroRemovalDialog.ShowAsync(); 58 | if (dialogResult == ContentDialogResult.Primary) 59 | { 60 | await helpers.ExecuteProcessAsynch("wsl.exe", $"--unregister {selectedDistroName}"); 61 | string distroStoragePath = Path.Combine(storageDirectory.Path, selectedDistroName); 62 | if(Directory.Exists(distroStoragePath)) 63 | { 64 | Directory.Delete(distroStoragePath, true); 65 | } 66 | await RefreshInstalledDistros(); 67 | } 68 | } 69 | 70 | private async void moreInfoButton_Click(object sender, RoutedEventArgs e) 71 | { 72 | var name = selectedDistroName; 73 | var version = WslSdk.InstalledDistros[name].version; 74 | var path = WslSdk.InstalledDistros[name].path; 75 | 76 | var dialogContent = new MoreInfoDialog(name, version, path); 77 | 78 | ContentDialog getMoreInfoDialog = new ContentDialog(); 79 | getMoreInfoDialog.XamlRoot = moreInfoButton.XamlRoot; 80 | getMoreInfoDialog.Title = "More info"; 81 | getMoreInfoDialog.CloseButtonText = "Close"; 82 | getMoreInfoDialog.Content = dialogContent; 83 | 84 | 85 | var result = await getMoreInfoDialog.ShowAsync(); 86 | 87 | } 88 | 89 | private async void setDefaultDistroButton_Click(object sender, RoutedEventArgs e) 90 | { 91 | await helpers.ExecuteProcessAsynch("wsl.exe", $"-s {selectedDistroName}"); 92 | } 93 | private void openFilesystemButton_Click(object sender, RoutedEventArgs e) 94 | { 95 | var path = Path.Combine(@"\\wsl$", selectedDistroName); 96 | Process.Start("explorer.exe", path); 97 | } 98 | 99 | private async void startDistroButton_Click(object sender, RoutedEventArgs e) 100 | { 101 | helpers.StartWSLDistroAsync(selectedDistroName); 102 | } 103 | 104 | private async void stopDistroButton_Click(object sender, RoutedEventArgs e) 105 | { 106 | await helpers.ExecuteProcessAsynch("wsl.exe", $"-t {selectedDistroName}"); 107 | } 108 | 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /easyWSL/ManageSnapshotsPage.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /easyWSL/ManageSnapshotsPage.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml; 2 | using Microsoft.UI.Xaml.Controls; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Diagnostics; 6 | using System.IO; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | using easyWslLib; 10 | 11 | 12 | namespace easyWSL 13 | { 14 | public sealed partial class ManageSnapshotsPage : Page 15 | { 16 | private WslSdk wslSdk = new(); 17 | private Windows.Storage.StorageFolder storageDirectory = Windows.Storage.ApplicationData.Current.LocalFolder; 18 | 19 | private Helpers helpers = new(); 20 | 21 | private List snapshotsList = new(); 22 | 23 | public string nameToRegister { get; set; } 24 | 25 | public ManageSnapshotsPage() 26 | { 27 | InitializeComponent(); 28 | RefreshDistros(); 29 | } 30 | 31 | public async Task RefreshDistros() 32 | { 33 | await WslSdk.GetInstalledDistributions(); 34 | var distrosList = WslSdk.InstalledDistros.Values.Select(o => o.name); 35 | distrosComboBox.ItemsSource = distrosList; 36 | 37 | FillSnapshotsListView(); 38 | } 39 | 40 | private void distrosComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 41 | { 42 | FillSnapshotsListView(); 43 | } 44 | 45 | private async void addSnapshotButton_Click(object sender, RoutedEventArgs e) 46 | { 47 | var snapshotsStoragePath = Path.Combine(storageDirectory.Path, "snapshots"); 48 | var distroName = distrosComboBox.SelectedItem as string; 49 | ShowProgressBar($"Creating snapshot of {distroName}"); 50 | 51 | Guid fileUUID = Guid.NewGuid(); 52 | var snapshotName = fileUUID.ToString(); 53 | 54 | var snapshotPath = Path.Combine(snapshotsStoragePath, distroName, $"{snapshotName}.tar.gz"); 55 | await helpers.ExecuteProcessAsynch("wsl.exe", $"--export {distroName} {snapshotPath}"); 56 | 57 | HideProgressBar(); 58 | 59 | ContentDialog succedDialog = new ContentDialog(); 60 | succedDialog.Title = "Succesfuly created snapshot"; 61 | succedDialog.CloseButtonText = "Cancel"; 62 | succedDialog.DefaultButton = ContentDialogButton.Close; 63 | FillSnapshotsListView(); 64 | } 65 | 66 | private void removeSnapshotButton_Click(object sender, RoutedEventArgs e) 67 | { 68 | int index = snapshotsListView.SelectedIndex; 69 | var snapshotPath = snapshotsList[index]; 70 | 71 | if (File.Exists(snapshotPath)) 72 | { 73 | File.Delete(snapshotPath); 74 | } 75 | string distro = distrosComboBox.SelectedValue as string; 76 | string path = Path.Combine(storageDirectory.Path, "snapshots", distro); 77 | if (Directory.Exists(path)) 78 | { 79 | int filesInDir = Directory.EnumerateFiles(path).Count(); 80 | if (filesInDir == 0) 81 | { 82 | Directory.Delete(path, true); 83 | } 84 | 85 | } 86 | FillSnapshotsListView(); 87 | } 88 | 89 | private async void FillSnapshotsListView() 90 | { 91 | await WslSdk.GetInstalledDistributions(); 92 | var distrosList = WslSdk.InstalledDistros.Values.Select(o => o.name); 93 | 94 | var snapshotsStoragePath = Path.Combine(storageDirectory.Path, "snapshots"); 95 | try 96 | { 97 | Directory.CreateDirectory(snapshotsStoragePath); 98 | } 99 | catch (Exception e) 100 | { 101 | await showErrorModal(); 102 | } 103 | foreach (string name in distrosList) 104 | { 105 | Directory.CreateDirectory(Path.Combine(snapshotsStoragePath, name)); 106 | } 107 | 108 | var distro = distrosComboBox.SelectedValue as string; 109 | if (distro == null) 110 | { 111 | return; 112 | } 113 | 114 | var snapshotsPath = Path.Combine(storageDirectory.Path, "snapshots", distro); 115 | snapshotsList = Directory.EnumerateFiles(snapshotsPath, "*.tar.gz").ToList(); 116 | 117 | List listviewLabels = new(); 118 | 119 | foreach (var snapshot in snapshotsList) 120 | { 121 | listviewLabels.Add(File.GetCreationTime(snapshot).ToString()); 122 | } 123 | 124 | snapshotsListView.ItemsSource = null; 125 | snapshotsListView.Items.Clear(); 126 | snapshotsListView.ItemsSource = listviewLabels; 127 | snapshotsListView.SelectedIndex = 0; 128 | 129 | if (snapshotsList.Count == 0) 130 | { 131 | snapshotsTitle.Text = $"There are no snapshots of {distro} distribution"; 132 | } 133 | else 134 | { 135 | snapshotsTitle.Text = $"Snapshots of {distro} distribution"; 136 | } 137 | } 138 | 139 | private void ShowProgressBar(string text) 140 | { 141 | snapshottingStatusTextBlock.Text = text; 142 | snapshottingStatusTextBlock.Visibility = Visibility.Visible; 143 | snapshottingProgressBar.Visibility = Visibility.Visible; 144 | } 145 | 146 | private void HideProgressBar() 147 | { 148 | snapshottingProgressBar.Visibility = Visibility.Collapsed; 149 | snapshottingStatusTextBlock.Visibility = Visibility.Collapsed; 150 | } 151 | 152 | private async void registerDistroFromSnapshotButton_Click(object sender, RoutedEventArgs e) 153 | { 154 | TextBox distroNameTextBox = new TextBox(); 155 | distroNameTextBox.Header = "Name"; 156 | 157 | ContentDialog dialog = new ContentDialog(); 158 | dialog.XamlRoot = registerDistroFromSnapshotButton.XamlRoot; 159 | dialog.Title = "Register from snapshot"; 160 | dialog.PrimaryButtonText = "Register"; 161 | dialog.CloseButtonText = "Cancel"; 162 | dialog.DefaultButton = ContentDialogButton.Primary; 163 | dialog.Content = distroNameTextBox; 164 | 165 | 166 | 167 | var result = await dialog.ShowAsync(); 168 | if (result == ContentDialogResult.Primary) 169 | { 170 | string name = distroNameTextBox.Text; 171 | 172 | if (name == "" || name.Contains(" ")) 173 | { 174 | await showErrorModal(); 175 | return; 176 | } 177 | else 178 | { 179 | int index = snapshotsListView.SelectedIndex; 180 | var snapshotPath = snapshotsList[index]; 181 | await RegisterDistro(name, snapshotPath); 182 | } 183 | } 184 | } 185 | 186 | private async Task RegisterDistro(string name, string path) 187 | { 188 | ShowProgressBar($"Registering the {name} distribution"); 189 | var distroStoragePath = Path.Combine(storageDirectory.Path, name); 190 | Directory.CreateDirectory(distroStoragePath); 191 | await helpers.ExecuteProcessAsynch("wsl.exe", $"--import {name} {distroStoragePath} {path}"); 192 | 193 | HideProgressBar(); 194 | 195 | ContentDialog registerDistroDialog = new ContentDialog(); 196 | registerDistroDialog.XamlRoot = registerDistroFromSnapshotButton.XamlRoot; 197 | registerDistroDialog.Title = $"{name} has been registered"; 198 | registerDistroDialog.SecondaryButtonText = "Close"; 199 | registerDistroDialog.PrimaryButtonText = "Run distribution"; 200 | registerDistroDialog.DefaultButton = ContentDialogButton.Primary; 201 | 202 | var result = await registerDistroDialog.ShowAsync(); 203 | 204 | if (result == ContentDialogResult.Primary) 205 | { 206 | helpers.StartWSLDistroAsync(name); 207 | } 208 | } 209 | 210 | private void openSnapshotsButton_Click(object sender, RoutedEventArgs e) 211 | { 212 | string distro = distrosComboBox.SelectedValue as string; 213 | string path = Path.Combine(storageDirectory.Path, "snapshots", distro); 214 | Process.Start("explorer.exe", path); 215 | } 216 | private async Task showErrorModal() 217 | { 218 | ContentDialog errorDialog = new ContentDialog(); 219 | errorDialog.XamlRoot = registerDistroFromSnapshotButton.XamlRoot; 220 | errorDialog.Title = "Error"; 221 | errorDialog.CloseButtonText = "Cancel"; 222 | errorDialog.DefaultButton = ContentDialogButton.Close; 223 | errorDialog.Content = "There were problems with registering your distribution."; 224 | await errorDialog.ShowAsync(); 225 | } 226 | } 227 | } 228 | 229 | -------------------------------------------------------------------------------- /easyWSL/MoreInfoDialog.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | Version 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /easyWSL/MoreInfoDialog.xaml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.UI.Xaml; 2 | using Microsoft.UI.Xaml.Controls; 3 | using Microsoft.UI.Xaml.Controls.Primitives; 4 | using Microsoft.UI.Xaml.Data; 5 | using Microsoft.UI.Xaml.Input; 6 | using Microsoft.UI.Xaml.Media; 7 | using Microsoft.UI.Xaml.Navigation; 8 | using System; 9 | using System.Collections.Generic; 10 | using System.Diagnostics; 11 | using System.IO; 12 | using System.Linq; 13 | using System.Runtime.InteropServices.WindowsRuntime; 14 | using Windows.Foundation; 15 | using Windows.Foundation.Collections; 16 | 17 | 18 | namespace easyWSL 19 | { 20 | 21 | public sealed partial class MoreInfoDialog : Page 22 | { 23 | private ManageDistrosPage manageDistrosPage = new(); 24 | 25 | public string name = ""; 26 | public string version = ""; 27 | public string path = ""; 28 | 29 | public MoreInfoDialog(string name, string version, string path) 30 | { 31 | this.InitializeComponent(); 32 | 33 | nameTextBox.Text = name; 34 | versionTextBlock.Text = version; 35 | pathTextBox.Text = path; 36 | } 37 | 38 | private void openVHDLocationButton_Click(object sender, RoutedEventArgs e) 39 | { 40 | Process.Start("explorer.exe", pathTextBox.Text); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /easyWSL/NavigationRoot_Window.xaml: -------------------------------------------------------------------------------- 1 |  9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | EasyWSL 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /easyWSL/NavigationRoot_Window.xaml.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.UI.Xaml; 3 | using Microsoft.UI.Xaml.Controls; 4 | 5 | namespace easyWSL 6 | { 7 | public sealed partial class NavigationRoot_Window : Window 8 | { 9 | public NavigationRoot_Window() 10 | { 11 | this.InitializeComponent(); 12 | ExtendsContentIntoTitleBar = true; 13 | SetTitleBar(TitleBar); 14 | } 15 | private void mainNavigation_ItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) 16 | { 17 | if (args.IsSettingsInvoked) 18 | { 19 | rootFrame.Navigate(typeof(SettingsPage)); 20 | } 21 | else 22 | { 23 | var item = sender.MenuItems.OfType().First(x => (string)x.Content == (string)args.InvokedItem); 24 | NavView_Navigate(item as NavigationViewItem); 25 | } 26 | } 27 | 28 | private void NavView_Navigate(NavigationViewItem item) 29 | { 30 | switch (item.Name) 31 | { 32 | case "manageDistributionsButton": 33 | rootFrame.Navigate(typeof(ManageDistrosPage)); 34 | break; 35 | 36 | case "addNewDistributionButton": 37 | rootFrame.Navigate(typeof(RegisterNewDistro_Page)); 38 | break; 39 | 40 | case "manageSnapshots": 41 | rootFrame.Navigate(typeof(ManageSnapshotsPage)); 42 | break; 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /easyWSL/Package.appxmanifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 10 | 11 | 15 | 16 | 17 | easyWSL 18 | Red Code Labs 19 | Assets\StoreLogo.png 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 35 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /easyWSL/PlatformHelpers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Net.Http.Headers; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using easyWslLib; 9 | using Windows.Storage.Streams; 10 | using Windows.Storage; 11 | using Windows.Web.Http; 12 | 13 | namespace easyWSL 14 | { 15 | internal class PlatformHelpers: IPlatformHelpers 16 | { 17 | private readonly Action _httpProgressCallback; 18 | public PlatformHelpers(string tarCommand, Action httpProgressCallback) 19 | { 20 | TarCommand = tarCommand; 21 | this._httpProgressCallback = httpProgressCallback; 22 | } 23 | public async Task CopyFileAsync(string sourcePath, string destinationPath) 24 | { 25 | string destinationFolderPath = sourcePath.Substring(0, sourcePath.LastIndexOf(@"\")); 26 | string destinationFileName = Path.GetFileName(destinationPath); 27 | 28 | StorageFile sourceFile = await StorageFile.GetFileFromPathAsync(sourcePath); 29 | StorageFolder destinationFolder = await StorageFolder.GetFolderFromPathAsync(destinationFolderPath); 30 | StorageFile destinationFile = await destinationFolder.CreateFileAsync(destinationFileName); 31 | 32 | IInputStream inputStream = await sourceFile.OpenAsync(FileAccessMode.Read); 33 | IOutputStream outputStream = await destinationFile.OpenAsync(FileAccessMode.ReadWrite); 34 | 35 | await RandomAccessStream.CopyAndCloseAsync(inputStream, outputStream); 36 | inputStream.Dispose(); 37 | outputStream.Dispose(); 38 | } 39 | 40 | public async Task DownloadFileAsync(Uri uri, IEnumerable> headers, FileInfo destinationPath) 41 | { 42 | HttpRequestHeaders _headers; 43 | 44 | var httpRequestMessage = new HttpRequestMessage 45 | { 46 | Method = HttpMethod.Get, 47 | RequestUri = uri, 48 | }; 49 | foreach (var header in headers) 50 | { 51 | httpRequestMessage.Headers.Add(header.Key, header.Value); 52 | } 53 | Progress progressCallback = new Progress(_httpProgressCallback); 54 | HttpResponseMessage response = await App.httpClient.SendRequestAsync(httpRequestMessage).AsTask(progressCallback); 55 | 56 | StorageFolder downloadFolder = await StorageFolder.GetFolderFromPathAsync(destinationPath.DirectoryName); 57 | StorageFile downloadFile = await downloadFolder.CreateFileAsync(destinationPath.Name); 58 | 59 | IInputStream inputStream = await response.Content.ReadAsInputStreamAsync(); 60 | IOutputStream outputStream = await downloadFile.OpenAsync(FileAccessMode.ReadWrite); 61 | await RandomAccessStream.CopyAndCloseAsync(inputStream, outputStream); 62 | 63 | 64 | inputStream.Dispose(); 65 | outputStream.Dispose(); 66 | } 67 | 68 | public string TarCommand { get; } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /easyWSL/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "easyWSL (Package)": { 4 | "commandName": "MsixPackage" 5 | }, 6 | "easyWSL (Unpackaged)": { 7 | "commandName": "Project" 8 | } 9 | } 10 | } -------------------------------------------------------------------------------- /easyWSL/RegisterNewDistro_Page.xaml: -------------------------------------------------------------------------------- 1 |  10 | 11 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Distribution details 26 | 27 | 28 | Supported distro list 29 | Docker Hub 30 | Local hard drive 31 | 32 | 33 | 34 | 35 | 36 | 37 | Supported image formats 38 | image:tag 39 | profile/image 40 | profile/image:tag 41 | 42 | 43 | Select a linux rootfs in *.tar or *.tar.bz format. 44 | 45 |