diff --git a/.pipelines/ESRPSigning_core.json b/.pipelines/ESRPSigning_core.json index 1388566d1f..c20e38e029 100644 --- a/.pipelines/ESRPSigning_core.json +++ b/.pipelines/ESRPSigning_core.json @@ -96,6 +96,7 @@ "PowerToys.SvgThumbnailProviderCpp.dll", "WinUI3Apps\\PowerToys.HostsModuleInterface.dll", + "WinUI3Apps\\PowerToys.HostsUILib.dll", "WinUI3Apps\\PowerToys.Hosts.dll", "WinUI3Apps\\PowerToys.Hosts.exe", @@ -113,6 +114,7 @@ "WinUI3Apps\\Powertoys.Peek.dll", "WinUI3Apps\\PowerToys.EnvironmentVariablesModuleInterface.dll", + "WinUI3Apps\\PowerToys.EnvironmentVariablesUILib.dll", "WinUI3Apps\\PowerToys.EnvironmentVariables.dll", "WinUI3Apps\\PowerToys.EnvironmentVariables.exe", @@ -186,6 +188,7 @@ "WinUI3Apps\\PowerRenameContextMenuPackage.msix", "WinUI3Apps\\PowerToys.RegistryPreviewExt.dll", + "WinUI3Apps\\PowerToys.RegistryPreviewUILib.dll", "WinUI3Apps\\PowerToys.RegistryPreview.dll", "WinUI3Apps\\PowerToys.RegistryPreview.exe", diff --git a/.pipelines/versionAndSignCheck.ps1 b/.pipelines/versionAndSignCheck.ps1 index 67c5312f95..1b15fe52db 100644 --- a/.pipelines/versionAndSignCheck.ps1 +++ b/.pipelines/versionAndSignCheck.ps1 @@ -20,7 +20,8 @@ $versionExceptions = @( "Microsoft.Xaml.Interactivity.dll", "hyjiacan.py4n.dll", "Microsoft.WindowsAppRuntime.Release.Net.dll", - "Microsoft.Windows.Widgets.Projection.dll") -join '|'; + "Microsoft.Windows.Widgets.Projection.dll", + "WinRT.Host.Shim.dll") -join '|'; $nullVersionExceptions = @( "codicon.ttf", "e_sqlite3.dll", diff --git a/Directory.Packages.props b/Directory.Packages.props index f8e3aa9aba..cad50dc2fa 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -97,4 +97,4 @@ - \ No newline at end of file + diff --git a/PowerToys.sln b/PowerToys.sln index ace30f844d..7d6e2aa8c3 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -448,7 +448,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MeasureToolUI", "src\module EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PowerAccentKeyboardService", "src\modules\poweraccent\PowerAccentKeyboardService\PowerAccentKeyboardService.vcxproj", "{C97D9A5D-206C-454E-997E-009E227D7F02}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hosts", "src\modules\Hosts\Hosts\Hosts.csproj", "{31D1C81D-765F-4446-AA62-E743F6325049}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsUILib", "src\modules\Hosts\HostsUILib\HostsUILib.csproj", "{31D1C81D-765F-4446-AA62-E743F6325049}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosts", "Hosts", "{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}" EndProject @@ -518,7 +518,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PastePlainModuleInterface", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AllExperiments", "src\common\AllExperiments\AllExperiments.csproj", "{9CE59ED5-7087-4353-88EB-788038A73CEC}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegistryPreviewUI", "src\modules\registrypreview\RegistryPreviewUI\RegistryPreviewUI.csproj", "{FD86C06A-FB54-4D5E-9831-1CDADF60D45F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegistryPreviewUILib", "src\modules\registrypreview\RegistryPreviewUILib\RegistryPreviewUILib.csproj", "{FD86C06A-FB54-4D5E-9831-1CDADF60D45F}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RegistryPreviewExt", "src\modules\registrypreview\RegistryPreviewExt\RegistryPreviewExt.vcxproj", "{697C6AF9-0A48-49A9-866C-67DA12384015}" EndProject @@ -546,7 +546,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnitTests-FancyZonesEditor" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvironmentVariables", "EnvironmentVariables", "{538ED0BB-B863-4B20-98CC-BCDF7FA0B68A}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariables", "src\modules\EnvironmentVariables\EnvironmentVariables\EnvironmentVariables.csproj", "{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariablesUILib", "src\modules\EnvironmentVariables\EnvironmentVariablesUILib\EnvironmentVariablesUILib.csproj", "{51465DA1-C18B-4B99-93E1-ECF8E0FA0CBA}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "EnvironmentVariablesModuleInterface", "src\modules\EnvironmentVariables\EnvironmentVariablesModuleInterface\EnvironmentVariablesModuleInterface.vcxproj", "{B9420661-B0E4-4241-ABD4-4A27A1F64250}" EndProject @@ -568,6 +568,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithContextMenu", EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithLib", "src\modules\FileLocksmith\FileLocksmithLib\FileLocksmithLib.vcxproj", "{9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hosts", "src\modules\Hosts\Hosts\Hosts.csproj", "{02DD46D3-F761-47D9-8894-2D6DA0124650}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RegistryPreview", "src\modules\registrypreview\RegistryPreview\RegistryPreview.csproj", "{8E23E173-7127-4A5F-9F93-3049F2B68047}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EnvironmentVariables", "src\modules\EnvironmentVariables\EnvironmentVariables\EnvironmentVariables.csproj", "{DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}" +EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZones", "src\modules\fancyzones\UITests-FancyZones\UITests-FancyZones.csproj", "{FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UITests-FancyZonesEditor", "src\modules\fancyzones\UITests-FancyZonesEditor\UITests-FancyZonesEditor.csproj", "{3A9A791E-94A9-49F8-8401-C11CE288D5FB}" @@ -2507,6 +2513,42 @@ Global {9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x64.Build.0 = Release|x64 {9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x86.ActiveCfg = Release|x64 {9D52FD25-EF90-4F9A-A015-91EFC5DAF54F}.Release|x86.Build.0 = Release|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Debug|ARM64.Build.0 = Debug|ARM64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Debug|x64.ActiveCfg = Debug|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Debug|x64.Build.0 = Debug|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Debug|x86.ActiveCfg = Debug|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Debug|x86.Build.0 = Debug|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Release|ARM64.ActiveCfg = Release|ARM64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Release|ARM64.Build.0 = Release|ARM64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Release|x64.ActiveCfg = Release|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Release|x64.Build.0 = Release|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Release|x86.ActiveCfg = Release|x64 + {02DD46D3-F761-47D9-8894-2D6DA0124650}.Release|x86.Build.0 = Release|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Debug|ARM64.Build.0 = Debug|ARM64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Debug|x64.ActiveCfg = Debug|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Debug|x64.Build.0 = Debug|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Debug|x86.ActiveCfg = Debug|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Debug|x86.Build.0 = Debug|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Release|ARM64.ActiveCfg = Release|ARM64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Release|ARM64.Build.0 = Release|ARM64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Release|x64.ActiveCfg = Release|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Release|x64.Build.0 = Release|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Release|x86.ActiveCfg = Release|x64 + {8E23E173-7127-4A5F-9F93-3049F2B68047}.Release|x86.Build.0 = Release|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Debug|ARM64.Build.0 = Debug|ARM64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Debug|x64.ActiveCfg = Debug|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Debug|x64.Build.0 = Debug|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Debug|x86.ActiveCfg = Debug|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Debug|x86.Build.0 = Debug|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|ARM64.ActiveCfg = Release|ARM64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|ARM64.Build.0 = Release|ARM64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x64.ActiveCfg = Release|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x64.Build.0 = Release|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x86.ActiveCfg = Release|x64 + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8}.Release|x86.Build.0 = Release|x64 {FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.ActiveCfg = Debug|ARM64 {FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|ARM64.Build.0 = Debug|ARM64 {FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52}.Debug|x64.ActiveCfg = Debug|x64 @@ -2764,6 +2806,9 @@ Global {0014D652-901F-4456-8D65-06FC5F997FB0} = {4C0D0746-BE5B-49EE-BD5D-A7811628AE8B} {799A50D8-DE89-4ED1-8FF8-AD5A9ED8C0CA} = {AB82E5DD-C32D-4F28-9746-2C780846188E} {9D52FD25-EF90-4F9A-A015-91EFC5DAF54F} = {AB82E5DD-C32D-4F28-9746-2C780846188E} + {02DD46D3-F761-47D9-8894-2D6DA0124650} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} + {8E23E173-7127-4A5F-9F93-3049F2B68047} = {929C1324-22E8-4412-A9A8-80E85F3985A5} + {DFF88D16-D36F-40A4-A955-CDCAA76EF7B8} = {538ED0BB-B863-4B20-98CC-BCDF7FA0B68A} {FE38FC07-1C05-4B57-ADA3-2FE2F53C6A52} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} {3A9A791E-94A9-49F8-8401-C11CE288D5FB} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} {C0974915-8A1D-4BF0-977B-9587D3807AB7} = {D1D6BC88-09AE-4FB4-AD24-5DED46A791DD} diff --git a/nuget.config b/nuget.config index cb38015f4a..e6a17ffdfe 100644 --- a/nuget.config +++ b/nuget.config @@ -1,3 +1,4 @@ + diff --git a/src/common/utils/modulesRegistry.h b/src/common/utils/modulesRegistry.h index fce782847d..8b957bd5b9 100644 --- a/src/common/utils/modulesRegistry.h +++ b/src/common/utils/modulesRegistry.h @@ -262,7 +262,7 @@ inline registry::ChangeSet getRegistryPreviewChangeSet(const std::wstring instal changes.push_back({ scope, L"Software\\Classes\\regfile\\shell\\preview\\command", std::nullopt, command }); std::wstring icon_path = installationDir; - icon_path.append(L"\\WinUI3Apps\\Assets\\RegistryPreview\\app.ico"); + icon_path.append(L"\\WinUI3Apps\\Assets\\RegistryPreview\\RegistryPreview.ico"); changes.push_back({ scope, L"Software\\Classes\\regfile\\shell\\preview", L"icon", icon_path }); return { changes }; diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj index 2c7035035d..b1543c1e78 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariables.csproj @@ -1,6 +1,5 @@  - WinExe net8.0-windows10.0.20348.0 @@ -8,6 +7,7 @@ 10.0.19041.0 EnvironmentVariables app.manifest + x86;x64;ARM64 win-x64;win-arm64 true true @@ -16,21 +16,36 @@ false false true + true + DISABLE_XAML_GENERATED_MAIN,TRACE ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps PowerToys.EnvironmentVariables - DISABLE_XAML_GENERATED_MAIN,TRACE - Assets/EnvironmentVariables/EnvironmentVariables.ico - true + Assets\EnvironmentVariables\EnvironmentVariables.ico PowerToys.EnvironmentVariables.pri - - - - + + + + + + + + + + + + + + + + + + + @@ -48,24 +63,11 @@ - - - - - - - - - - - - - - - - - - + + + + + @@ -73,23 +75,10 @@ - - - - - - - - - - - - - + + true + diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml index d4b0dc7bbc..bdf5b059b1 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml @@ -1,4 +1,4 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs index ca2fdb72b8..3907a2ba3a 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/App.xaml.cs @@ -4,8 +4,11 @@ using System; using System.IO.Abstractions; -using EnvironmentVariables.Helpers; -using EnvironmentVariables.ViewModels; +using EnvironmentVariables.Telemetry; +using EnvironmentVariablesUILib; +using EnvironmentVariablesUILib.Helpers; +using EnvironmentVariablesUILib.Telemetry; +using EnvironmentVariablesUILib.ViewModels; using ManagedCommon; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -47,8 +50,11 @@ namespace EnvironmentVariables services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); }).Build(); UnhandledException += App_UnhandledException; @@ -85,8 +91,7 @@ namespace EnvironmentVariables Logger.LogInfo($"EnvironmentVariables started detached from PowerToys Runner."); } - PowerToysTelemetry.Log.WriteEvent(new EnvironmentVariables.Telemetry.EnvironmentVariablesOpenedEvent()); - + PowerToysTelemetry.Log.WriteEvent(new Telemetry.EnvironmentVariablesOpenedEvent()); window = new MainWindow(); window.Activate(); } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml index b5d7dafdb1..78d46d85c7 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml @@ -6,7 +6,6 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:EnvironmentVariables" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" - xmlns:views="using:EnvironmentVariables.Views" xmlns:winuiex="using:WinUIEx" x:Uid="Window" MinWidth="700" @@ -15,7 +14,7 @@ - + @@ -42,6 +41,5 @@ VerticalAlignment="Center" Style="{StaticResource CaptionTextBlockStyle}" /> - diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs index 4ab2cd4e5f..a40dac4ef2 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/MainWindow.xaml.cs @@ -4,11 +4,14 @@ using System; using System.Runtime.InteropServices; -using EnvironmentVariables.Helpers; -using EnvironmentVariables.Helpers.Win32; -using EnvironmentVariables.ViewModels; +using EnvironmentVariables.Win32; +using EnvironmentVariablesUILib; +using EnvironmentVariablesUILib.Helpers; +using EnvironmentVariablesUILib.ViewModels; using ManagedCommon; using Microsoft.UI.Dispatching; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; using WinUIEx; namespace EnvironmentVariables @@ -18,6 +21,8 @@ namespace EnvironmentVariables /// public sealed partial class MainWindow : WindowEx { + private EnvironmentVariablesMainPage MainPage { get; } + public MainWindow() { this.InitializeComponent(); @@ -35,6 +40,14 @@ namespace EnvironmentVariables RegisterWindow(handle); WindowHelpers.BringToForeground(handle); + + MainPage = App.GetService(); + } + + private void Grid_Loaded(object sender, RoutedEventArgs e) + { + MainGrid.Children.Add(MainPage); + Grid.SetRow(MainPage, 1); } private static readonly DispatcherQueue _dispatcherQueue = DispatcherQueue.GetForCurrentThread(); @@ -61,7 +74,7 @@ namespace EnvironmentVariables if (wParam != (IntPtr)0x12345) { var viewModel = App.GetService(); - viewModel.EnvironmentState = Models.EnvironmentState.EnvironmentMessageReceived; + viewModel.EnvironmentState = EnvironmentVariablesUILib.Models.EnvironmentState.EnvironmentMessageReceived; } } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Styles/TextBlock.xaml b/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Styles/TextBlock.xaml deleted file mode 100644 index bf6d01383b..0000000000 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Styles/TextBlock.xaml +++ /dev/null @@ -1,8 +0,0 @@ - - - 12 - - \ No newline at end of file diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/LoggerWrapper.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/LoggerWrapper.cs new file mode 100644 index 0000000000..f91a4467fa --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/LoggerWrapper.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using EnvironmentVariablesUILib.Helpers; +using ManagedCommon; + +namespace EnvironmentVariables +{ + internal sealed class LoggerWrapper : ILogger + { + public void LogDebug(string message) + { + Logger.LogDebug(message); + } + + public void LogError(string message) + { + Logger.LogError(message); + } + + public void LogError(string message, Exception ex) + { + Logger.LogError(message, ex); + } + + public void LogInfo(string message) + { + Logger.LogInfo(message); + } + + public void LogTrace() + { + Logger.LogTrace(); + } + + public void LogWarning(string message) + { + Logger.LogWarning(message); + } + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/NativeMethods.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/NativeMethods.cs index 1ca3e2428c..1d94d08fc6 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/NativeMethods.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/NativeMethods.cs @@ -5,7 +5,7 @@ using System; using System.Runtime.InteropServices; -namespace EnvironmentVariables.Helpers.Win32 +namespace EnvironmentVariables.Win32 { public static class NativeMethods { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/EnvironmentVariablesVariableChangedEvent.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/EnvironmentVariablesVariableChangedEvent.cs index 1583adb9fa..15b240822d 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/EnvironmentVariablesVariableChangedEvent.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/EnvironmentVariablesVariableChangedEvent.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Diagnostics.Tracing; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Models; using Microsoft.PowerToys.Telemetry; using Microsoft.PowerToys.Telemetry.Events; diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/TelemetryWrapper.cs b/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/TelemetryWrapper.cs new file mode 100644 index 0000000000..30d350a578 --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/Telemetry/TelemetryWrapper.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using EnvironmentVariablesUILib.Models; +using EnvironmentVariablesUILib.Telemetry; +using Microsoft.PowerToys.Telemetry; + +namespace EnvironmentVariables.Telemetry +{ + internal sealed class TelemetryWrapper : ITelemetry + { + public void LogEnvironmentVariablesProfileEnabledEvent(bool enabled) + { + var telemetryEnabled = new EnvironmentVariablesProfileEnabledEvent() + { + Enabled = enabled, + }; + + PowerToysTelemetry.Log.WriteEvent(telemetryEnabled); + } + + public void LogEnvironmentVariablesVariableChangedEvent(VariablesSetType type) + { + PowerToysTelemetry.Log.WriteEvent(new Telemetry.EnvironmentVariablesVariableChangedEvent(type)); + } + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/app.manifest b/src/modules/EnvironmentVariables/EnvironmentVariables/app.manifest index cbe8c5420c..dd46c0d7b7 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/app.manifest +++ b/src/modules/EnvironmentVariables/EnvironmentVariables/app.manifest @@ -4,12 +4,9 @@ - - - + diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/EnvironmentVariables.ico b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/EnvironmentVariables.ico new file mode 100644 index 0000000000..dc07264100 Binary files /dev/null and b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/EnvironmentVariables.ico differ diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Assets/EnvironmentVariables/ProfileIcon.png b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/ProfileIcon.png similarity index 100% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Assets/EnvironmentVariables/ProfileIcon.png rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/ProfileIcon.png diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Assets/EnvironmentVariables/SystemIcon.png b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/SystemIcon.png similarity index 100% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Assets/EnvironmentVariables/SystemIcon.png rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/SystemIcon.png diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Assets/EnvironmentVariables/UserIcon.png b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/UserIcon.png similarity index 100% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Assets/EnvironmentVariables/UserIcon.png rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Assets/EnvironmentVariables/UserIcon.png diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToBoolConverter.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToBoolConverter.cs similarity index 89% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToBoolConverter.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToBoolConverter.cs index 81e1ef1efd..95aae3e874 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToBoolConverter.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToBoolConverter.cs @@ -3,10 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Models; using Microsoft.UI.Xaml.Data; -namespace EnvironmentVariables.Converters; +namespace EnvironmentVariablesUILib.Converters; public class EnvironmentStateToBoolConverter : IValueConverter { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToMessageConverter.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToMessageConverter.cs similarity index 90% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToMessageConverter.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToMessageConverter.cs index ffe473ef28..5f1103fe21 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToMessageConverter.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToMessageConverter.cs @@ -3,11 +3,11 @@ // See the LICENSE file in the project root for more information. using System; -using EnvironmentVariables.Helpers; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Helpers; +using EnvironmentVariablesUILib.Models; using Microsoft.UI.Xaml.Data; -namespace EnvironmentVariables.Converters; +namespace EnvironmentVariablesUILib.Converters; public class EnvironmentStateToMessageConverter : IValueConverter { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToTitleConverter.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToTitleConverter.cs similarity index 87% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToTitleConverter.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToTitleConverter.cs index 344c9b1072..dbe2843919 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToTitleConverter.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToTitleConverter.cs @@ -3,11 +3,11 @@ // See the LICENSE file in the project root for more information. using System; -using EnvironmentVariables.Helpers; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Helpers; +using EnvironmentVariablesUILib.Models; using Microsoft.UI.Xaml.Data; -namespace EnvironmentVariables.Converters; +namespace EnvironmentVariablesUILib.Converters; public class EnvironmentStateToTitleConverter : IValueConverter { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToVisibilityConverter.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToVisibilityConverter.cs similarity index 89% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToVisibilityConverter.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToVisibilityConverter.cs index 682a93cc13..4c2d2b42da 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/EnvironmentStateToVisibilityConverter.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/EnvironmentStateToVisibilityConverter.cs @@ -3,11 +3,11 @@ // See the LICENSE file in the project root for more information. using System; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Models; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Data; -namespace EnvironmentVariables.Converters; +namespace EnvironmentVariablesUILib.Converters; public class EnvironmentStateToVisibilityConverter : IValueConverter { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/VariableTypeToGlyphConverter.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/VariableTypeToGlyphConverter.cs similarity index 91% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/VariableTypeToGlyphConverter.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/VariableTypeToGlyphConverter.cs index fc6ec01f30..41cf4124cb 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Converters/VariableTypeToGlyphConverter.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Converters/VariableTypeToGlyphConverter.cs @@ -3,10 +3,10 @@ // See the LICENSE file in the project root for more information. using System; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Models; using Microsoft.UI.Xaml.Data; -namespace EnvironmentVariables.Converters; +namespace EnvironmentVariablesUILib.Converters; public class VariableTypeToGlyphConverter : IValueConverter { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml similarity index 76% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml index 5be8dc688d..de06561b50 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml @@ -1,13 +1,13 @@  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 12 + + - - - - - diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml.cs similarity index 98% rename from src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml.cs index 7ca3c00456..e99bc6bc53 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/EnvironmentVariablesXAML/Views/MainPage.xaml.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesMainPage.xaml.cs @@ -3,19 +3,17 @@ // See the LICENSE file in the project root for more information. using System; -using System.Collections.ObjectModel; using System.Linq; using System.Threading.Tasks; using System.Windows.Input; using CommunityToolkit.Mvvm.Input; -using EnvironmentVariables.Models; -using EnvironmentVariables.ViewModels; +using EnvironmentVariablesUILib.Models; +using EnvironmentVariablesUILib.ViewModels; using Microsoft.UI.Xaml.Controls; -using Windows.Foundation.Collections; -namespace EnvironmentVariables.Views +namespace EnvironmentVariablesUILib { - public sealed partial class MainPage : Page + public sealed partial class EnvironmentVariablesMainPage : Page { private sealed class RelayCommandParameter { @@ -46,11 +44,13 @@ namespace EnvironmentVariables.Views public ICommand AddDefaultVariableCommand => new RelayCommand(AddDefaultVariable); - public MainPage() + public EnvironmentVariablesMainPage(MainViewModel viewModel) { this.InitializeComponent(); - ViewModel = App.GetService(); + ViewModel = viewModel; DataContext = ViewModel; + + ViewModel.LoadEnvironmentVariables(); } private async Task ShowEditDialogAsync(Variable variable, VariablesSet parentSet) diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj new file mode 100644 index 0000000000..e0322d5389 --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/EnvironmentVariablesUILib.csproj @@ -0,0 +1,68 @@ + + + + + Library + net8.0-windows10.0.20348 + EnvironmentVariablesUILib + true + true + false + false + PowerToys.EnvironmentVariablesUILib + + PowerToys.EnvironmentVariablesUILib.pri + true + true + + + + + + + + + + + + + + + + + + + + true + DEBUG;TRACE + full + prompt + 4 + false + + + + TRACE + true + pdbonly + prompt + 4 + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/ElevationHelper.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ElevationHelper.cs similarity index 81% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/ElevationHelper.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ElevationHelper.cs index 9b3bc16e2f..a2b0239c73 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/ElevationHelper.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ElevationHelper.cs @@ -4,7 +4,7 @@ using System.Security.Principal; -namespace EnvironmentVariables.Helpers +namespace EnvironmentVariablesUILib.Helpers { public class ElevationHelper : IElevationHelper { @@ -16,5 +16,7 @@ namespace EnvironmentVariables.Helpers { _isElevated = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator); } + + public static IElevationHelper ElevationHelperInstance { get; set; } } } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/EnvironmentVariablesHelper.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesHelper.cs similarity index 97% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/EnvironmentVariablesHelper.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesHelper.cs index 9503f9fb1b..9cd01b970a 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/EnvironmentVariablesHelper.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesHelper.cs @@ -5,12 +5,11 @@ using System; using System.Collections; using System.Collections.Generic; -using EnvironmentVariables.Helpers.Win32; -using EnvironmentVariables.Models; -using ManagedCommon; +using EnvironmentVariablesUILib.Helpers.Win32; +using EnvironmentVariablesUILib.Models; using Microsoft.Win32; -namespace EnvironmentVariables.Helpers +namespace EnvironmentVariablesUILib.Helpers { internal sealed class EnvironmentVariablesHelper { @@ -73,7 +72,7 @@ namespace EnvironmentVariables.Helpers const int MaxUserEnvVariableLength = 255; // User-wide env vars stored in the registry have names limited to 255 chars if (!fromMachine && variable.Length >= MaxUserEnvVariableLength) { - Logger.LogError("Can't apply variable - name too long."); + LoggerInstance.Logger.LogError("Can't apply variable - name too long."); return; } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/EnvironmentVariablesService.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesService.cs similarity index 91% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/EnvironmentVariablesService.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesService.cs index 6fde9872fc..8a21b793a6 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/EnvironmentVariablesService.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/EnvironmentVariablesService.cs @@ -8,11 +8,11 @@ using System.IO; using System.IO.Abstractions; using System.Text.Json; using System.Threading.Tasks; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Models; -namespace EnvironmentVariables.Helpers +namespace EnvironmentVariablesUILib.Helpers { - internal sealed class EnvironmentVariablesService : IEnvironmentVariablesService + public sealed class EnvironmentVariablesService : IEnvironmentVariablesService { private const string ProfilesJsonFileSubPath = "Microsoft\\PowerToys\\EnvironmentVariables\\"; diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/IElevationHelper.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/IElevationHelper.cs similarity index 86% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/IElevationHelper.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/IElevationHelper.cs index 0b27b0a544..e52a6d374a 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/IElevationHelper.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/IElevationHelper.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace EnvironmentVariables.Helpers +namespace EnvironmentVariablesUILib.Helpers { public interface IElevationHelper { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/IEnvironmentVariablesService.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/IEnvironmentVariablesService.cs similarity index 85% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/IEnvironmentVariablesService.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/IEnvironmentVariablesService.cs index 5a1604ab1b..8213d56920 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/IEnvironmentVariablesService.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/IEnvironmentVariablesService.cs @@ -5,9 +5,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using EnvironmentVariables.Models; +using EnvironmentVariablesUILib.Models; -namespace EnvironmentVariables.Helpers +namespace EnvironmentVariablesUILib.Helpers { public interface IEnvironmentVariablesService : IDisposable { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ILogger.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ILogger.cs new file mode 100644 index 0000000000..86623417a0 --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ILogger.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace EnvironmentVariablesUILib.Helpers +{ + public interface ILogger + { + public void LogError(string message); + + public void LogError(string message, Exception ex); + + public void LogWarning(string message); + + public void LogInfo(string message); + + public void LogDebug(string message); + + public void LogTrace(); + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/LoggerInstance.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/LoggerInstance.cs new file mode 100644 index 0000000000..7adfa208a4 --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/LoggerInstance.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +namespace EnvironmentVariablesUILib.Helpers +{ + public static class LoggerInstance + { + public static ILogger Logger { get; set; } + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/NativeMethods.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/NativeMethods.cs new file mode 100644 index 0000000000..d3ce76b5b5 --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/NativeMethods.cs @@ -0,0 +1,54 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Runtime.InteropServices; + +namespace EnvironmentVariablesUILib.Helpers.Win32 +{ + public static class NativeMethods + { + internal const int HWND_BROADCAST = 0xffff; + + internal delegate IntPtr WinProc(IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam); + + [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] + internal static extern int SendNotifyMessage(IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam); + + [DllImport("User32.dll")] + internal static extern int GetDpiForWindow(IntPtr hwnd); + + [DllImport("user32.dll", EntryPoint = "SetWindowLong")] + internal static extern int SetWindowLong32(IntPtr hWnd, WindowLongIndexFlags nIndex, WinProc newProc); + + [DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")] + internal static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, WindowLongIndexFlags nIndex, WinProc newProc); + + [DllImport("user32.dll")] + internal static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, WindowMessage msg, IntPtr wParam, IntPtr lParam); + + [Flags] + internal enum WindowLongIndexFlags : int + { + GWL_WNDPROC = -4, + } + + internal enum WindowMessage : int + { + WM_SETTINGSCHANGED = 0x001A, + } + + internal static IntPtr SetWindowLongPtr(IntPtr hWnd, WindowLongIndexFlags nIndex, WinProc newProc) + { + if (IntPtr.Size == 8) + { + return SetWindowLongPtr64(hWnd, nIndex, newProc); + } + else + { + return new IntPtr(SetWindowLong32(hWnd, nIndex, newProc)); + } + } + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/ResourceLoaderInstance.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ResourceLoaderInstance.cs similarity index 61% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/ResourceLoaderInstance.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ResourceLoaderInstance.cs index b0a11730b9..f6a6da44ce 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Helpers/ResourceLoaderInstance.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Helpers/ResourceLoaderInstance.cs @@ -3,15 +3,15 @@ // See the LICENSE file in the project root for more information. using Microsoft.Windows.ApplicationModel.Resources; -namespace EnvironmentVariables.Helpers +namespace EnvironmentVariablesUILib.Helpers { - internal static class ResourceLoaderInstance + public static class ResourceLoaderInstance { - internal static ResourceLoader ResourceLoader { get; private set; } + public static ResourceLoader ResourceLoader { get; private set; } static ResourceLoaderInstance() { - ResourceLoader = new ResourceLoader("PowerToys.EnvironmentVariables.pri"); + ResourceLoader = new ResourceLoader("PowerToys.EnvironmentVariablesUILib.pri", "PowerToys.EnvironmentVariablesUILib/Resources"); } } } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/DefaultVariablesSet.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/DefaultVariablesSet.cs similarity index 90% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Models/DefaultVariablesSet.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/DefaultVariablesSet.cs index 9c07c1df3b..f356f4dbb5 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/DefaultVariablesSet.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/DefaultVariablesSet.cs @@ -4,7 +4,7 @@ using System; -namespace EnvironmentVariables.Models +namespace EnvironmentVariablesUILib.Models { public class DefaultVariablesSet : VariablesSet { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/EnvironmentState.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/EnvironmentState.cs similarity index 89% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Models/EnvironmentState.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/EnvironmentState.cs index 12837055cd..ecf2e9cf3e 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/EnvironmentState.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/EnvironmentState.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace EnvironmentVariables.Models +namespace EnvironmentVariablesUILib.Models { public enum EnvironmentState { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/ProfileVariablesSet.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/ProfileVariablesSet.cs similarity index 90% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Models/ProfileVariablesSet.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/ProfileVariablesSet.cs index db9306efa7..1480de3aef 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/ProfileVariablesSet.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/ProfileVariablesSet.cs @@ -6,10 +6,9 @@ using System; using System.Collections.ObjectModel; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; -using EnvironmentVariables.Helpers; -using ManagedCommon; +using EnvironmentVariablesUILib.Helpers; -namespace EnvironmentVariables.Models +namespace EnvironmentVariablesUILib.Models { public partial class ProfileVariablesSet : VariablesSet { @@ -48,13 +47,13 @@ namespace EnvironmentVariables.Models // Backup the variable if (!EnvironmentVariablesHelper.SetVariableWithoutNotify(variableToOverride)) { - Logger.LogError("Failed to set backup variable."); + LoggerInstance.Logger.LogError("Failed to set backup variable."); } } if (!EnvironmentVariablesHelper.SetVariableWithoutNotify(variable)) { - Logger.LogError("Failed to set profile variable."); + LoggerInstance.Logger.LogError("Failed to set profile variable."); } } @@ -80,7 +79,7 @@ namespace EnvironmentVariables.Models // Unset the variable if (!EnvironmentVariablesHelper.UnsetVariableWithoutNotify(variable)) { - Logger.LogError("Failed to unset variable."); + LoggerInstance.Logger.LogError("Failed to unset variable."); } var originalName = variable.Name; @@ -95,12 +94,12 @@ namespace EnvironmentVariables.Models if (!EnvironmentVariablesHelper.UnsetVariableWithoutNotify(backupVariable)) { - Logger.LogError("Failed to unset backup variable."); + LoggerInstance.Logger.LogError("Failed to unset backup variable."); } if (!EnvironmentVariablesHelper.SetVariableWithoutNotify(variableToRestore)) { - Logger.LogError("Failed to restore backup variable."); + LoggerInstance.Logger.LogError("Failed to restore backup variable."); } } } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/Variable.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/Variable.cs similarity index 90% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Models/Variable.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/Variable.cs index 029b66feb2..0401384cd8 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/Variable.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/Variable.cs @@ -10,10 +10,9 @@ using System.Linq; using System.Text.Json.Serialization; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; -using EnvironmentVariables.Helpers; -using ManagedCommon; +using EnvironmentVariablesUILib.Helpers; -namespace EnvironmentVariables.Models +namespace EnvironmentVariablesUILib.Models { public partial class Variable : ObservableObject, IJsonOnDeserialized { @@ -38,7 +37,7 @@ namespace EnvironmentVariables.Models { get { - return (ParentType != VariablesSetType.System || App.GetService().IsElevated) && !IsAppliedFromProfile; + return (ParentType != VariablesSetType.System || ElevationHelper.ElevationHelperInstance.IsElevated) && !IsAppliedFromProfile; } } @@ -122,7 +121,7 @@ namespace EnvironmentVariables.Models { if (!EnvironmentVariablesHelper.UnsetVariable(clone)) { - Logger.LogError("Failed to unset original variable."); + LoggerInstance.Logger.LogError("Failed to unset original variable."); } if (parentProfile != null) @@ -137,12 +136,12 @@ namespace EnvironmentVariables.Models if (!EnvironmentVariablesHelper.UnsetVariableWithoutNotify(backupVariable)) { - Logger.LogError("Failed to unset backup variable."); + LoggerInstance.Logger.LogError("Failed to unset backup variable."); } if (!EnvironmentVariablesHelper.SetVariableWithoutNotify(variableToRestore)) { - Logger.LogError("Failed to restore backup variable."); + LoggerInstance.Logger.LogError("Failed to restore backup variable."); } } } @@ -163,14 +162,14 @@ namespace EnvironmentVariables.Models // Backup the variable if (!EnvironmentVariablesHelper.SetVariableWithoutNotify(variableToOverride)) { - Logger.LogError("Failed to set backup variable."); + LoggerInstance.Logger.LogError("Failed to set backup variable."); } } } if (!EnvironmentVariablesHelper.SetVariable(this)) { - Logger.LogError("Failed to set new variable."); + LoggerInstance.Logger.LogError("Failed to set new variable."); } } }); @@ -197,7 +196,7 @@ namespace EnvironmentVariables.Models const int MaxUserEnvVariableLength = 255; // User-wide env vars stored in the registry have names limited to 255 chars if (ParentType != VariablesSetType.System && Name.Length >= MaxUserEnvVariableLength) { - Logger.LogError("Variable name too long."); + LoggerInstance.Logger.LogError("Variable name too long."); return false; } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/VariablesSet.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/VariablesSet.cs similarity index 96% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Models/VariablesSet.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/VariablesSet.cs index a1e352d4e9..237fe7a910 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/VariablesSet.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/VariablesSet.cs @@ -7,9 +7,9 @@ using System.Collections.ObjectModel; using System.Linq; using System.Text.Json.Serialization; using CommunityToolkit.Mvvm.ComponentModel; -using EnvironmentVariables.ViewModels; +using EnvironmentVariablesUILib.ViewModels; -namespace EnvironmentVariables.Models +namespace EnvironmentVariablesUILib.Models { public partial class VariablesSet : ObservableObject { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/VariablesSetType.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/VariablesSetType.cs similarity index 88% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Models/VariablesSetType.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/VariablesSetType.cs index 6b59b05b68..e9605e0dd6 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/Models/VariablesSetType.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Models/VariablesSetType.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace EnvironmentVariables.Models +namespace EnvironmentVariablesUILib.Models { public enum VariablesSetType { diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/Strings/en-us/Resources.resw b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Strings/en-us/Resources.resw similarity index 100% rename from src/modules/EnvironmentVariables/EnvironmentVariables/Strings/en-us/Resources.resw rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Strings/en-us/Resources.resw diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Telemetry/ITelemetry.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Telemetry/ITelemetry.cs new file mode 100644 index 0000000000..509365835b --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Telemetry/ITelemetry.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using EnvironmentVariablesUILib.Models; + +namespace EnvironmentVariablesUILib.Telemetry +{ + public interface ITelemetry + { + abstract void LogEnvironmentVariablesProfileEnabledEvent(bool enabled); + + abstract void LogEnvironmentVariablesVariableChangedEvent(VariablesSetType type); + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Telemetry/TelemetryInstance.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Telemetry/TelemetryInstance.cs new file mode 100644 index 0000000000..a58fe1f407 --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Telemetry/TelemetryInstance.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +using EnvironmentVariablesUILib.Telemetry; + +namespace EnvironmentVariablesUILib.Helpers +{ + public static class TelemetryInstance + { + public static ITelemetry Telemetry { get; set; } + } +} diff --git a/src/modules/EnvironmentVariables/EnvironmentVariables/ViewModels/MainViewModel.cs b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/ViewModels/MainViewModel.cs similarity index 92% rename from src/modules/EnvironmentVariables/EnvironmentVariables/ViewModels/MainViewModel.cs rename to src/modules/EnvironmentVariables/EnvironmentVariablesUILib/ViewModels/MainViewModel.cs index 8bc7b208dc..cd261845ab 100644 --- a/src/modules/EnvironmentVariables/EnvironmentVariables/ViewModels/MainViewModel.cs +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/ViewModels/MainViewModel.cs @@ -10,14 +10,12 @@ using System.Globalization; using System.Linq; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; -using EnvironmentVariables.Helpers; -using EnvironmentVariables.Models; -using ManagedCommon; -using Microsoft.PowerToys.Telemetry; +using EnvironmentVariablesUILib.Helpers; +using EnvironmentVariablesUILib.Models; +using EnvironmentVariablesUILib.Telemetry; using Microsoft.UI.Dispatching; -namespace EnvironmentVariables.ViewModels +namespace EnvironmentVariablesUILib.ViewModels { public partial class MainViewModel : ObservableObject { @@ -48,10 +46,15 @@ namespace EnvironmentVariables.ViewModels public ProfileVariablesSet AppliedProfile { get; set; } - public MainViewModel(IEnvironmentVariablesService environmentVariablesService) + public MainViewModel(IElevationHelper elevationHelper, IEnvironmentVariablesService environmentVariablesService, ILogger logger, ITelemetry telemetry) { _environmentVariablesService = environmentVariablesService; - var isElevated = App.GetService().IsElevated; + + ElevationHelper.ElevationHelperInstance = elevationHelper; + LoggerInstance.Logger = logger; + TelemetryInstance.Telemetry = telemetry; + + var isElevated = ElevationHelper.ElevationHelperInstance.IsElevated; IsElevated = isElevated; } @@ -85,7 +88,6 @@ namespace EnvironmentVariables.ViewModels } } - [RelayCommand] public void LoadEnvironmentVariables() { LoadDefaultVariables(); @@ -129,7 +131,7 @@ namespace EnvironmentVariables.ViewModels catch (Exception ex) { // Show some error - Logger.LogError("Failed to load profiles.json file", ex); + LoggerInstance.Logger.LogError("Failed to load profiles.json file", ex); Profiles = new ObservableCollection(); } @@ -228,8 +230,7 @@ namespace EnvironmentVariables.ViewModels }); }); - PowerToysTelemetry.Log.WriteEvent(new Telemetry.EnvironmentVariablesVariableChangedEvent(original.ParentType)); - + TelemetryInstance.Telemetry.LogEnvironmentVariablesVariableChangedEvent(original.ParentType); _ = Task.Run(SaveAsync); } } @@ -276,7 +277,7 @@ namespace EnvironmentVariables.ViewModels catch (Exception ex) { // Show some error - Logger.LogError("Failed to save to profiles.json file", ex); + LoggerInstance.Logger.LogError("Failed to save to profiles.json file", ex); } } @@ -293,23 +294,13 @@ namespace EnvironmentVariables.ViewModels UnsetAppliedProfile(); SetAppliedProfile(profile); - var telemetryEnabled = new Telemetry.EnvironmentVariablesProfileEnabledEvent() - { - Enabled = true, - }; - - PowerToysTelemetry.Log.WriteEvent(telemetryEnabled); + TelemetryInstance.Telemetry.LogEnvironmentVariablesProfileEnabledEvent(true); } else { UnsetAppliedProfile(); - var telemetryEnabled = new Telemetry.EnvironmentVariablesProfileEnabledEvent() - { - Enabled = false, - }; - - PowerToysTelemetry.Log.WriteEvent(telemetryEnabled); + TelemetryInstance.Telemetry.LogEnvironmentVariablesProfileEnabledEvent(false); } } } diff --git a/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/app.manifest b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/app.manifest new file mode 100644 index 0000000000..cbe8c5420c --- /dev/null +++ b/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/app.manifest @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + PerMonitorV2 + + + \ No newline at end of file diff --git a/src/modules/Hosts/Hosts.Tests/EntryTest.cs b/src/modules/Hosts/Hosts.Tests/EntryTest.cs index 04b02b4879..c6360af428 100644 --- a/src/modules/Hosts/Hosts.Tests/EntryTest.cs +++ b/src/modules/Hosts/Hosts.Tests/EntryTest.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -using Hosts.Models; +using HostsUILib.Models; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Hosts.Tests diff --git a/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj b/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj index 3e789295e5..340dbebe39 100644 --- a/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj +++ b/src/modules/Hosts/Hosts.Tests/Hosts.Tests.csproj @@ -33,7 +33,7 @@ - + diff --git a/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs b/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs index d76beebd60..1eeef3b752 100644 --- a/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs +++ b/src/modules/Hosts/Hosts.Tests/HostsServiceTest.cs @@ -5,14 +5,13 @@ using System.IO.Abstractions.TestingHelpers; using System.Linq; using System.Threading.Tasks; -using Hosts.Exceptions; -using Hosts.Helpers; -using Hosts.Models; -using Hosts.Settings; using Hosts.Tests.Mocks; +using HostsUILib.Exceptions; +using HostsUILib.Helpers; +using HostsUILib.Models; +using HostsUILib.Settings; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; -using Settings.UI.Library.Enumerations; namespace Hosts.Tests { diff --git a/src/modules/Hosts/Hosts/Helpers/Host.cs b/src/modules/Hosts/Hosts/Helpers/Host.cs new file mode 100644 index 0000000000..1627f359ea --- /dev/null +++ b/src/modules/Hosts/Hosts/Helpers/Host.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using Microsoft.Extensions.Hosting; + +namespace Hosts.Helpers +{ + public static class Host + { + public static IHost HostInstance + { + get; set; + } + + public static T GetService() + where T : class + { + if (HostInstance!.Services.GetService(typeof(T)) is not T service) + { + throw new ArgumentException($"{typeof(T)} needs to be registered in ConfigureServices within App.xaml.cs."); + } + + return service; + } + } +} diff --git a/src/modules/Hosts/Hosts/Helpers/LoggerWrapper.cs b/src/modules/Hosts/Hosts/Helpers/LoggerWrapper.cs new file mode 100644 index 0000000000..89ec07d25e --- /dev/null +++ b/src/modules/Hosts/Hosts/Helpers/LoggerWrapper.cs @@ -0,0 +1,43 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using HostsUILib.Helpers; +using ManagedCommon; + +namespace Hosts +{ + internal sealed class LoggerWrapper : ILogger + { + public void LogDebug(string message) + { + Logger.LogDebug(message); + } + + public void LogError(string message) + { + Logger.LogError(message); + } + + public void LogError(string message, Exception ex) + { + Logger.LogError(message, ex); + } + + public void LogInfo(string message) + { + Logger.LogInfo(message); + } + + public void LogTrace() + { + Logger.LogTrace(); + } + + public void LogWarning(string message) + { + Logger.LogWarning(message); + } + } +} diff --git a/src/modules/Hosts/Hosts/Hosts.csproj b/src/modules/Hosts/Hosts/Hosts.csproj index ba13f01b00..e097b575dd 100644 --- a/src/modules/Hosts/Hosts/Hosts.csproj +++ b/src/modules/Hosts/Hosts/Hosts.csproj @@ -1,6 +1,6 @@  - + WinExe net8.0-windows10.0.20348.0 @@ -16,15 +16,34 @@ false true ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps - Hosts PowerToys.Hosts DISABLE_XAML_GENERATED_MAIN,TRACE - Assets/Hosts/Hosts.ico true + Assets/Hosts/Hosts.ico PowerToys.Hosts.pri + + + + + + + + + + + + + + + + + + + + @@ -32,6 +51,10 @@ + + + + win-x64 @@ -46,38 +69,38 @@ $(OutDir) false - - - - - - - - - - - - + - - - + + - - - + + + + - + + + true + diff --git a/src/modules/Hosts/Hosts/HostsXAML/App.xaml b/src/modules/Hosts/Hosts/HostsXAML/App.xaml index 7d19cc0d8d..e053137314 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/App.xaml +++ b/src/modules/Hosts/Hosts/HostsXAML/App.xaml @@ -1,4 +1,5 @@ - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs b/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs index 34080ce130..2d03c2ea28 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs +++ b/src/modules/Hosts/Hosts/HostsXAML/App.xaml.cs @@ -1,48 +1,43 @@ -// Copyright (c) Microsoft Corporation +// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.IO.Abstractions; using System.Threading; -using Hosts.Helpers; -using Hosts.Settings; -using Hosts.ViewModels; -using Hosts.Views; +using Common.UI; +using HostsUILib.Helpers; +using HostsUILib.Settings; +using HostsUILib.ViewModels; +using HostsUILib.Views; using ManagedCommon; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.PowerToys.Telemetry; using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; +using static HostsUILib.Settings.IUserSettings; +using Host = Hosts.Helpers.Host; +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. namespace Hosts { + /// + /// Provides application-specific behavior to supplement the default Application class. + /// public partial class App : Application { - private Window _window; - - public IHost Host - { - get; - } - - public static T GetService() - where T : class - { - if ((App.Current as App)!.Host.Services.GetService(typeof(T)) is not T service) - { - throw new ArgumentException($"{typeof(T)} needs to be registered in ConfigureServices within App.xaml.cs."); - } - - return service; - } - + /// + /// Initializes a new instance of the class. + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// public App() { InitializeComponent(); - Host = Microsoft.Extensions.Hosting.Host. + Host.HostInstance = Microsoft.Extensions.Hosting.Host. CreateDefaultBuilder(). UseContentRoot(AppContext.BaseDirectory). ConfigureServices((context, services) => @@ -50,28 +45,33 @@ namespace Hosts // Core Services services.AddSingleton(); services.AddSingleton(); - services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); // Views and ViewModels - services.AddTransient(); - services.AddTransient(); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(() => + { + SettingsDeepLink.OpenSettings(SettingsDeepLink.SettingsWindow.Hosts, true); + }); + + services.AddSingleton(); + services.AddSingleton(); }). Build(); - UnhandledException += App_UnhandledException; - var cleanupBackupThread = new Thread(() => { // Delete old backups only if running elevated - if (!GetService().IsElevated) + if (!Host.GetService().IsElevated) { return; } try { - GetService().CleanupBackup(); + Host.GetService().CleanupBackup(); } catch (Exception ex) { @@ -81,8 +81,14 @@ namespace Hosts cleanupBackupThread.IsBackground = true; cleanupBackupThread.Start(); + + UnhandledException += App_UnhandledException; } + /// + /// Invoked when the application is launched. + /// + /// Details about the launch request and process. protected override void OnLaunched(LaunchActivatedEventArgs args) { var cmdArgs = Environment.GetCommandLineArgs(); @@ -105,15 +111,17 @@ namespace Hosts Logger.LogInfo($"Hosts started detached from PowerToys Runner."); } - PowerToysTelemetry.Log.WriteEvent(new Hosts.Telemetry.HostsFileEditorOpenedEvent()); + PowerToysTelemetry.Log.WriteEvent(new Telemetry.HostsFileEditorOpenedEvent()); - _window = new MainWindow(); - _window.Activate(); + window = new MainWindow(); + window.Activate(); } private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e) { Logger.LogError("Unhandled exception", e.Exception); } + + private Window window; } } diff --git a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml index 37c43fa4fc..2537c462ca 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml +++ b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml @@ -1,9 +1,8 @@ - - + @@ -42,7 +41,5 @@ VerticalAlignment="Center" Style="{StaticResource CaptionTextBlockStyle}" /> - - diff --git a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs index d6a474b841..3f8c01de83 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs +++ b/src/modules/Hosts/Hosts/HostsXAML/MainWindow.xaml.cs @@ -1,17 +1,28 @@ -// Copyright (c) Microsoft Corporation +// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using Hosts.Helpers; +using HostsUILib.Helpers; +using HostsUILib.Views; using ManagedCommon; using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; +using Microsoft.Windows.ApplicationModel.Resources; using WinUIEx; +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. namespace Hosts { + /// + /// An empty window that can be used on its own or navigated to within a Frame. + /// public sealed partial class MainWindow : WindowEx { + private HostsMainPage MainPage { get; } + public MainWindow() { InitializeComponent(); @@ -20,15 +31,18 @@ namespace Hosts SetTitleBar(titleBar); AppWindow.SetIcon("Assets/Hosts/Hosts.ico"); - var loader = ResourceLoaderInstance.ResourceLoader; - var title = App.GetService().IsElevated ? loader.GetString("WindowAdminTitle") : loader.GetString("WindowTitle"); + var loader = new ResourceLoader("PowerToys.HostsUILib.pri", "PowerToys.HostsUILib/Resources"); + + var title = Host.GetService().IsElevated ? loader.GetString("WindowAdminTitle") : loader.GetString("WindowTitle"); Title = title; AppTitleTextBlock.Text = title; var handle = this.GetWindowHandle(); - WindowHelpers.BringToForeground(handle); + WindowHelpers.BringToForeground(handle); Activated += MainWindow_Activated; + + MainPage = Host.GetService(); } private void MainWindow_Activated(object sender, WindowActivatedEventArgs args) @@ -42,5 +56,11 @@ namespace Hosts AppTitleTextBlock.Foreground = (SolidColorBrush)App.Current.Resources["WindowCaptionForeground"]; } } + + private void Grid_Loaded(object sender, RoutedEventArgs e) + { + MainGrid.Children.Add(MainPage); + Grid.SetRow(MainPage, 1); + } } } diff --git a/src/modules/Hosts/Hosts/Program.cs b/src/modules/Hosts/Hosts/Program.cs index 4b41f3c71a..5b7c21861b 100644 --- a/src/modules/Hosts/Hosts/Program.cs +++ b/src/modules/Hosts/Hosts/Program.cs @@ -16,7 +16,6 @@ namespace Hosts public static void Main(string[] args) { Logger.InitializeLogger("\\Hosts\\Logs"); - WinRT.ComWrappersSupport.InitializeComWrappers(); if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredHostsFileEditorEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled) diff --git a/src/modules/Hosts/Hosts/Settings/UserSettings.cs b/src/modules/Hosts/Hosts/Settings/UserSettings.cs index 5c73dd3a17..42e2848c18 100644 --- a/src/modules/Hosts/Hosts/Settings/UserSettings.cs +++ b/src/modules/Hosts/Hosts/Settings/UserSettings.cs @@ -5,10 +5,11 @@ using System; using System.IO.Abstractions; using System.Threading; +using HostsUILib.Helpers; +using HostsUILib.Settings; using ManagedCommon; using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library.Utilities; -using Settings.UI.Library.Enumerations; namespace Hosts.Settings { @@ -38,8 +39,10 @@ namespace Hosts.Settings } } + // Moved from Settings.UI.Library public HostsAdditionalLinesPosition AdditionalLinesPosition { get; private set; } + // Moved from Settings.UI.Library public HostsEncoding Encoding { get; set; } public UserSettings() @@ -72,6 +75,7 @@ namespace Hosts.Settings if (!_settingsUtils.SettingsExists(HostsModuleName)) { + // Logger needs to be abstracted Logger.LogInfo("Hosts settings.json was missing, creating a new one"); var defaultSettings = new HostsSettings(); defaultSettings.Save(_settingsUtils); @@ -81,8 +85,8 @@ namespace Hosts.Settings if (settings != null) { ShowStartupWarning = settings.Properties.ShowStartupWarning; - AdditionalLinesPosition = settings.Properties.AdditionalLinesPosition; - Encoding = settings.Properties.Encoding; + AdditionalLinesPosition = (HostsAdditionalLinesPosition)settings.Properties.AdditionalLinesPosition; + Encoding = (HostsEncoding)settings.Properties.Encoding; LoopbackDuplicates = settings.Properties.LoopbackDuplicates; } diff --git a/src/modules/Hosts/Hosts/app.manifest b/src/modules/Hosts/Hosts/app.manifest index 6417c11e2d..ca937b4b2a 100644 --- a/src/modules/Hosts/Hosts/app.manifest +++ b/src/modules/Hosts/Hosts/app.manifest @@ -1,5 +1,6 @@ - + @@ -18,4 +19,4 @@ - + \ No newline at end of file diff --git a/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-100.png b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-100.png new file mode 100644 index 0000000000..adcd8d708a Binary files /dev/null and b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-100.png differ diff --git a/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-125.png b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-125.png new file mode 100644 index 0000000000..4ff1604ac8 Binary files /dev/null and b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-125.png differ diff --git a/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-150.png b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-150.png new file mode 100644 index 0000000000..e46ae0acdb Binary files /dev/null and b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-150.png differ diff --git a/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-200.png b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-200.png new file mode 100644 index 0000000000..a585ff9ad6 Binary files /dev/null and b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-200.png differ diff --git a/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-400.png b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-400.png new file mode 100644 index 0000000000..612c354231 Binary files /dev/null and b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/AppList.scale-400.png differ diff --git a/src/modules/Hosts/HostsUILib/Assets/HostsUILib/Hosts.ico b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/Hosts.ico new file mode 100644 index 0000000000..d3fcce766e Binary files /dev/null and b/src/modules/Hosts/HostsUILib/Assets/HostsUILib/Hosts.ico differ diff --git a/src/modules/Hosts/Hosts/Consts.cs b/src/modules/Hosts/HostsUILib/Consts.cs similarity index 95% rename from src/modules/Hosts/Hosts/Consts.cs rename to src/modules/Hosts/HostsUILib/Consts.cs index 3772f34279..37819452e4 100644 --- a/src/modules/Hosts/Hosts/Consts.cs +++ b/src/modules/Hosts/HostsUILib/Consts.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Hosts +namespace HostsUILib { public static class Consts { diff --git a/src/modules/Hosts/Hosts/Exceptions/NotRunningElevatedException.cs b/src/modules/Hosts/HostsUILib/Exceptions/NotRunningElevatedException.cs similarity index 89% rename from src/modules/Hosts/Hosts/Exceptions/NotRunningElevatedException.cs rename to src/modules/Hosts/HostsUILib/Exceptions/NotRunningElevatedException.cs index 4aa428a270..14a1f96d8f 100644 --- a/src/modules/Hosts/Hosts/Exceptions/NotRunningElevatedException.cs +++ b/src/modules/Hosts/HostsUILib/Exceptions/NotRunningElevatedException.cs @@ -4,7 +4,7 @@ using System; -namespace Hosts.Exceptions +namespace HostsUILib.Exceptions { public class NotRunningElevatedException : Exception { diff --git a/src/modules/Hosts/Hosts/Exceptions/ReadOnlyHostsException.cs b/src/modules/Hosts/HostsUILib/Exceptions/ReadOnlyHostsException.cs similarity index 89% rename from src/modules/Hosts/Hosts/Exceptions/ReadOnlyHostsException.cs rename to src/modules/Hosts/HostsUILib/Exceptions/ReadOnlyHostsException.cs index 76685aac4a..fc273851d6 100644 --- a/src/modules/Hosts/Hosts/Exceptions/ReadOnlyHostsException.cs +++ b/src/modules/Hosts/HostsUILib/Exceptions/ReadOnlyHostsException.cs @@ -4,7 +4,7 @@ using System; -namespace Hosts.Exceptions +namespace HostsUILib.Exceptions { public class ReadOnlyHostsException : Exception { diff --git a/src/modules/Hosts/Hosts/Helpers/ElevationHelper.cs b/src/modules/Hosts/HostsUILib/Helpers/ElevationHelper.cs similarity index 95% rename from src/modules/Hosts/Hosts/Helpers/ElevationHelper.cs rename to src/modules/Hosts/HostsUILib/Helpers/ElevationHelper.cs index 306ba02bea..1a4f9cf700 100644 --- a/src/modules/Hosts/Hosts/Helpers/ElevationHelper.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/ElevationHelper.cs @@ -4,7 +4,7 @@ using System.Security.Principal; -namespace Hosts.Helpers +namespace HostsUILib.Helpers { public class ElevationHelper : IElevationHelper { diff --git a/src/modules/Hosts/Hosts/Helpers/ExpressionExtensions.cs b/src/modules/Hosts/HostsUILib/Helpers/ExpressionExtensions.cs similarity index 97% rename from src/modules/Hosts/Hosts/Helpers/ExpressionExtensions.cs rename to src/modules/Hosts/HostsUILib/Helpers/ExpressionExtensions.cs index a72265ab24..7ad0f8b8ad 100644 --- a/src/modules/Hosts/Hosts/Helpers/ExpressionExtensions.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/ExpressionExtensions.cs @@ -5,7 +5,7 @@ using System; using System.Linq.Expressions; -namespace Hosts.Helpers +namespace HostsUILib.Helpers { // https://stackoverflow.com/a/22569086 public static class ExpressionExtensions diff --git a/src/modules/Hosts/Hosts/Helpers/HostsService.cs b/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs similarity index 97% rename from src/modules/Hosts/Hosts/Helpers/HostsService.cs rename to src/modules/Hosts/HostsUILib/Helpers/HostsService.cs index ec58c149de..08fbde86c8 100644 --- a/src/modules/Hosts/Hosts/Helpers/HostsService.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/HostsService.cs @@ -13,14 +13,12 @@ using System.Net.NetworkInformation; using System.Text; using System.Threading; using System.Threading.Tasks; -using Hosts.Exceptions; -using Hosts.Models; -using Hosts.Settings; -using ManagedCommon; +using HostsUILib.Exceptions; +using HostsUILib.Models; +using HostsUILib.Settings; using Microsoft.Win32; -using Settings.UI.Library.Enumerations; -namespace Hosts.Helpers +namespace HostsUILib.Helpers { public class HostsService : IHostsService, IDisposable { @@ -277,7 +275,7 @@ namespace Hosts.Helpers } catch (Exception ex) { - Logger.LogError("Failed to open default editor", ex); + LoggerInstance.Logger.LogError("Failed to open default editor", ex); notepadFallback = true; } @@ -289,7 +287,7 @@ namespace Hosts.Helpers } catch (Exception ex) { - Logger.LogError("Failed to open notepad", ex); + LoggerInstance.Logger.LogError("Failed to open notepad", ex); } } } diff --git a/src/modules/Hosts/Hosts/Helpers/IElevationHelper.cs b/src/modules/Hosts/HostsUILib/Helpers/IElevationHelper.cs similarity index 90% rename from src/modules/Hosts/Hosts/Helpers/IElevationHelper.cs rename to src/modules/Hosts/HostsUILib/Helpers/IElevationHelper.cs index 122949e6a2..592dbc39d9 100644 --- a/src/modules/Hosts/Hosts/Helpers/IElevationHelper.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/IElevationHelper.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Hosts.Helpers +namespace HostsUILib.Helpers { public interface IElevationHelper { diff --git a/src/modules/Hosts/Hosts/Helpers/IHostsService.cs b/src/modules/Hosts/HostsUILib/Helpers/IHostsService.cs similarity index 92% rename from src/modules/Hosts/Hosts/Helpers/IHostsService.cs rename to src/modules/Hosts/HostsUILib/Helpers/IHostsService.cs index cf35db07a1..d97add2e7a 100644 --- a/src/modules/Hosts/Hosts/Helpers/IHostsService.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/IHostsService.cs @@ -5,9 +5,9 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; -using Hosts.Models; +using HostsUILib.Models; -namespace Hosts.Helpers +namespace HostsUILib.Helpers { public interface IHostsService : IDisposable { diff --git a/src/modules/Hosts/HostsUILib/Helpers/ILogger.cs b/src/modules/Hosts/HostsUILib/Helpers/ILogger.cs new file mode 100644 index 0000000000..cb9f9a9d40 --- /dev/null +++ b/src/modules/Hosts/HostsUILib/Helpers/ILogger.cs @@ -0,0 +1,23 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; + +namespace HostsUILib.Helpers +{ + public interface ILogger + { + public void LogError(string message); + + public void LogError(string message, Exception ex); + + public void LogWarning(string message); + + public void LogInfo(string message); + + public void LogDebug(string message); + + public void LogTrace(); + } +} diff --git a/src/modules/Hosts/HostsUILib/Helpers/LoggerInstance.cs b/src/modules/Hosts/HostsUILib/Helpers/LoggerInstance.cs new file mode 100644 index 0000000000..754d1268a0 --- /dev/null +++ b/src/modules/Hosts/HostsUILib/Helpers/LoggerInstance.cs @@ -0,0 +1,10 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +namespace HostsUILib.Helpers +{ + public static class LoggerInstance + { + public static ILogger Logger { get; set; } + } +} diff --git a/src/modules/registrypreview/RegistryPreviewUI/ResourceLoaderInstance.cs b/src/modules/Hosts/HostsUILib/Helpers/ResourceLoaderInstance.cs similarity index 80% rename from src/modules/registrypreview/RegistryPreviewUI/ResourceLoaderInstance.cs rename to src/modules/Hosts/HostsUILib/Helpers/ResourceLoaderInstance.cs index 88d4a194d8..94591894da 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/ResourceLoaderInstance.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/ResourceLoaderInstance.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Windows.ApplicationModel.Resources; -namespace RegistryPreview +namespace HostsUILib.Helpers { internal static class ResourceLoaderInstance { @@ -11,7 +11,7 @@ namespace RegistryPreview static ResourceLoaderInstance() { - ResourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("PowerToys.RegistryPreview.pri"); + ResourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("PowerToys.HostsUILib.pri", "PowerToys.HostsUILib/Resources"); } } } diff --git a/src/modules/Hosts/Hosts/Helpers/StringHelper.cs b/src/modules/Hosts/HostsUILib/Helpers/StringHelper.cs similarity index 93% rename from src/modules/Hosts/Hosts/Helpers/StringHelper.cs rename to src/modules/Hosts/HostsUILib/Helpers/StringHelper.cs index 56992d54e5..b33a4ec676 100644 --- a/src/modules/Hosts/Hosts/Helpers/StringHelper.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/StringHelper.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Hosts.Helpers +namespace HostsUILib.Helpers { public static class StringHelper { diff --git a/src/modules/Hosts/Hosts/Helpers/ValidationHelper.cs b/src/modules/Hosts/HostsUILib/Helpers/ValidationHelper.cs similarity index 98% rename from src/modules/Hosts/Hosts/Helpers/ValidationHelper.cs rename to src/modules/Hosts/HostsUILib/Helpers/ValidationHelper.cs index 6a10772299..e0c70142ef 100644 --- a/src/modules/Hosts/Hosts/Helpers/ValidationHelper.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/ValidationHelper.cs @@ -5,7 +5,7 @@ using System; using System.Text.RegularExpressions; -namespace Hosts.Helpers +namespace HostsUILib.Helpers { public static class ValidationHelper { diff --git a/src/modules/Hosts/Hosts/Helpers/VisualTreeUtils.cs b/src/modules/Hosts/HostsUILib/Helpers/VisualTreeUtils.cs similarity index 98% rename from src/modules/Hosts/Hosts/Helpers/VisualTreeUtils.cs rename to src/modules/Hosts/HostsUILib/Helpers/VisualTreeUtils.cs index 4be55866d9..1b84fbdcad 100644 --- a/src/modules/Hosts/Hosts/Helpers/VisualTreeUtils.cs +++ b/src/modules/Hosts/HostsUILib/Helpers/VisualTreeUtils.cs @@ -5,7 +5,7 @@ using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Media; -namespace Hosts.Helpers +namespace HostsUILib.Helpers { // Taken from https://github.com/microsoft/microsoft-ui-xaml/blob/main/test/MUXControlsTestApp/Utilities/VisualTreeUtils.cs // Original copyright header: diff --git a/src/modules/Hosts/Hosts/HostsXAML/Views/MainPage.xaml b/src/modules/Hosts/HostsUILib/HostsMainPage.xaml similarity index 66% rename from src/modules/Hosts/Hosts/HostsXAML/Views/MainPage.xaml rename to src/modules/Hosts/HostsUILib/HostsMainPage.xaml index 8c5b744fb5..448140f794 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/Views/MainPage.xaml +++ b/src/modules/Hosts/HostsUILib/HostsMainPage.xaml @@ -1,14 +1,14 @@  - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/Hosts/Hosts/HostsXAML/Views/MainPage.xaml.cs b/src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs similarity index 91% rename from src/modules/Hosts/Hosts/HostsXAML/Views/MainPage.xaml.cs rename to src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs index e573fbeb54..8af0289975 100644 --- a/src/modules/Hosts/Hosts/HostsXAML/Views/MainPage.xaml.cs +++ b/src/modules/Hosts/HostsUILib/HostsMainPage.xaml.cs @@ -6,18 +6,16 @@ using System; using System.Threading.Tasks; using System.Windows.Input; using CommunityToolkit.Mvvm.Input; -using Hosts.Helpers; -using Hosts.Models; -using Hosts.Settings; -using Hosts.ViewModels; -using ManagedCommon; +using HostsUILib.Helpers; +using HostsUILib.Models; +using HostsUILib.ViewModels; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Input; -namespace Hosts.Views +namespace HostsUILib.Views { - public sealed partial class MainPage : Page + public partial class HostsMainPage : Page { public MainViewModel ViewModel { get; private set; } @@ -35,10 +33,11 @@ namespace Hosts.Views public ICommand ExitCommand => new RelayCommand(() => { Microsoft.UI.Dispatching.DispatcherQueue.GetForCurrentThread().TryEnqueue(Application.Current.Exit); }); - public MainPage() + public HostsMainPage(MainViewModel viewModel) { InitializeComponent(); - ViewModel = App.GetService(); + ViewModel = viewModel; + DataContext = ViewModel; } @@ -128,7 +127,9 @@ namespace Hosts.Views private async void Page_Loaded(object sender, RoutedEventArgs e) { - var userSettings = App.GetService(); + ViewModel.ReadHosts(); + + var userSettings = ViewModel.UserSettings; if (userSettings.ShowStartupWarning) { var resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader; @@ -219,11 +220,14 @@ namespace Hosts.Views { // Based on the template from dev/CommonStyles/ContentDialog_themeresources.xaml in https://github.com/microsoft/microsoft-ui-xaml var border = VisualTreeUtils.FindVisualChildByName(sender as ContentDialog, "BackgroundElement") as Border; - border.Margin = new Thickness(0, 32, 0, 0); // Should be the size reserved for the title bar as in MainWindow.xaml + if (border is not null) + { + border.Margin = new Thickness(0, 32, 0, 0); // Should be the size reserved for the title bar as in MainWindow. + } } catch (Exception ex) { - Logger.LogError("Couldn't set the margin for a content dialog. It will appear on top of the title bar.", ex); + LoggerInstance.Logger.LogError("Couldn't set the margin for a content dialog. It will appear on top of the title bar.", ex); } } } diff --git a/src/modules/Hosts/HostsUILib/HostsUILib.csproj b/src/modules/Hosts/HostsUILib/HostsUILib.csproj new file mode 100644 index 0000000000..2ae4fe4068 --- /dev/null +++ b/src/modules/Hosts/HostsUILib/HostsUILib.csproj @@ -0,0 +1,69 @@ + + + + + Library + net8.0-windows10.0.20348 + HostsUILib + true + true + false + false + PowerToys.HostsUILib + + PowerToys.HostsUILib.pri + + true + true + + + + + + + + + + + + + + + + + + + + true + DEBUG;TRACE + full + prompt + 4 + false + + + + TRACE + true + pdbonly + prompt + 4 + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/Hosts/Hosts/Models/AddressType.cs b/src/modules/Hosts/HostsUILib/Models/AddressType.cs similarity index 91% rename from src/modules/Hosts/Hosts/Models/AddressType.cs rename to src/modules/Hosts/HostsUILib/Models/AddressType.cs index f89a950218..46987144a2 100644 --- a/src/modules/Hosts/Hosts/Models/AddressType.cs +++ b/src/modules/Hosts/HostsUILib/Models/AddressType.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace Hosts.Models +namespace HostsUILib.Models { public enum AddressType { diff --git a/src/modules/Hosts/Hosts/Models/Entry.cs b/src/modules/Hosts/HostsUILib/Models/Entry.cs similarity index 98% rename from src/modules/Hosts/Hosts/Models/Entry.cs rename to src/modules/Hosts/HostsUILib/Models/Entry.cs index a1c62edd24..8cc8530d38 100644 --- a/src/modules/Hosts/Hosts/Models/Entry.cs +++ b/src/modules/Hosts/HostsUILib/Models/Entry.cs @@ -6,9 +6,9 @@ using System; using System.Net; using System.Text; using CommunityToolkit.Mvvm.ComponentModel; -using Hosts.Helpers; +using HostsUILib.Helpers; -namespace Hosts.Models +namespace HostsUILib.Models { public partial class Entry : ObservableObject { diff --git a/src/modules/Hosts/Hosts/Models/HostsData.cs b/src/modules/Hosts/HostsUILib/Models/HostsData.cs similarity index 97% rename from src/modules/Hosts/Hosts/Models/HostsData.cs rename to src/modules/Hosts/HostsUILib/Models/HostsData.cs index abb79a69ef..706660f56b 100644 --- a/src/modules/Hosts/Hosts/Models/HostsData.cs +++ b/src/modules/Hosts/HostsUILib/Models/HostsData.cs @@ -5,7 +5,7 @@ using System.Collections.Generic; using System.Collections.ObjectModel; -namespace Hosts.Models +namespace HostsUILib.Models { /// /// Represents the parsed hosts file diff --git a/src/modules/Hosts/HostsUILib/Settings/HostsAdditionalLinesPosition.cs b/src/modules/Hosts/HostsUILib/Settings/HostsAdditionalLinesPosition.cs new file mode 100644 index 0000000000..62c78f64ab --- /dev/null +++ b/src/modules/Hosts/HostsUILib/Settings/HostsAdditionalLinesPosition.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace HostsUILib.Settings +{ + public enum HostsAdditionalLinesPosition + { + Top = 0, + Bottom = 1, + } +} diff --git a/src/modules/Hosts/HostsUILib/Settings/HostsEncoding.cs b/src/modules/Hosts/HostsUILib/Settings/HostsEncoding.cs new file mode 100644 index 0000000000..ae72516e29 --- /dev/null +++ b/src/modules/Hosts/HostsUILib/Settings/HostsEncoding.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace HostsUILib.Settings +{ + public enum HostsEncoding + { + Utf8 = 0, + Utf8Bom = 1, + } +} diff --git a/src/modules/Hosts/Hosts/Settings/IUserSettings.cs b/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs similarity index 83% rename from src/modules/Hosts/Hosts/Settings/IUserSettings.cs rename to src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs index fabea87e62..13f1761ceb 100644 --- a/src/modules/Hosts/Hosts/Settings/IUserSettings.cs +++ b/src/modules/Hosts/HostsUILib/Settings/IUserSettings.cs @@ -3,9 +3,9 @@ // See the LICENSE file in the project root for more information. using System; -using Settings.UI.Library.Enumerations; +using System.Net; -namespace Hosts.Settings +namespace HostsUILib.Settings { public interface IUserSettings { @@ -18,5 +18,7 @@ namespace Hosts.Settings public HostsEncoding Encoding { get; } event EventHandler LoopbackDuplicatesChanged; + + public delegate void OpenSettingsFunction(); } } diff --git a/src/modules/Hosts/Hosts/Strings/en-us/Resources.resw b/src/modules/Hosts/HostsUILib/Strings/en-us/Resources.resw similarity index 100% rename from src/modules/Hosts/Hosts/Strings/en-us/Resources.resw rename to src/modules/Hosts/HostsUILib/Strings/en-us/Resources.resw diff --git a/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs b/src/modules/Hosts/HostsUILib/ViewModels/MainViewModel.cs similarity index 94% rename from src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs rename to src/modules/Hosts/HostsUILib/ViewModels/MainViewModel.cs index 414fb8fce2..1a756d5124 100644 --- a/src/modules/Hosts/Hosts/ViewModels/MainViewModel.cs +++ b/src/modules/Hosts/HostsUILib/ViewModels/MainViewModel.cs @@ -10,19 +10,18 @@ using System.Linq; using System.Linq.Expressions; using System.Threading; using System.Threading.Tasks; -using Common.UI; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using CommunityToolkit.WinUI; using CommunityToolkit.WinUI.Collections; -using Hosts.Exceptions; -using Hosts.Helpers; -using Hosts.Models; -using Hosts.Settings; -using ManagedCommon; +using HostsUILib.Exceptions; +using HostsUILib.Helpers; +using HostsUILib.Models; +using HostsUILib.Settings; using Microsoft.UI.Dispatching; +using static HostsUILib.Settings.IUserSettings; -namespace Hosts.ViewModels +namespace HostsUILib.ViewModels { public partial class MainViewModel : ObservableObject, IDisposable { @@ -90,13 +89,22 @@ namespace Hosts.ViewModels public int NextId => _entries?.Count > 0 ? _entries.Max(e => e.Id) + 1 : 0; - public MainViewModel(IHostsService hostService, IUserSettings userSettings) + public IUserSettings UserSettings => _userSettings; + + public static MainViewModel Instance { get; set; } + + private OpenSettingsFunction _openSettingsFunction; + + public MainViewModel(IHostsService hostService, IUserSettings userSettings, ILogger logger, OpenSettingsFunction openSettingsFunction) { _hostsService = hostService; _userSettings = userSettings; _hostsService.FileChanged += (s, e) => _dispatcherQueue.TryEnqueue(() => FileChanged = true); _userSettings.LoopbackDuplicatesChanged += (s, e) => ReadHosts(); + + LoggerInstance.Logger = logger; + _openSettingsFunction = openSettingsFunction; } public void Add(Entry entry) @@ -270,7 +278,7 @@ namespace Hosts.ViewModels [RelayCommand] public void OpenSettings() { - SettingsDeepLink.OpenSettings(SettingsDeepLink.SettingsWindow.Hosts, true); + _openSettingsFunction(); } [RelayCommand] @@ -335,7 +343,7 @@ namespace Hosts.ViewModels } catch (OperationCanceledException) { - Logger.LogInfo("FindDuplicates cancelled"); + LoggerInstance.Logger.LogInfo("FindDuplicates cancelled"); return; } } @@ -424,7 +432,7 @@ namespace Hosts.ViewModels } catch (Exception ex) { - Logger.LogError("Failed to save hosts file", ex); + LoggerInstance.Logger.LogError("Failed to save hosts file", ex); var resourceLoader = ResourceLoaderInstance.ResourceLoader; errorMessage = resourceLoader.GetString("FileSaveError_Generic"); } diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/app.ico b/src/modules/registrypreview/RegistryPreview/Assets/RegistryPreview/RegistryPreview.ico similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/app.ico rename to src/modules/registrypreview/RegistryPreview/Assets/RegistryPreview/RegistryPreview.ico diff --git a/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs b/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs new file mode 100644 index 0000000000..34de7f1752 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview/MainWindow.Events.cs @@ -0,0 +1,33 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.UI.Xaml; +using Windows.Data.Json; +using WinUIEx; + +namespace RegistryPreview +{ + public sealed partial class MainWindow : WindowEx + { + /// + /// Event handler to grab the main window's size and position before it closes + /// + private void AppWindow_Closing(Microsoft.UI.Windowing.AppWindow sender, Microsoft.UI.Windowing.AppWindowClosingEventArgs args) + { + jsonWindowPlacement.SetNamedValue("appWindow.Position.X", JsonValue.CreateNumberValue(appWindow.Position.X)); + jsonWindowPlacement.SetNamedValue("appWindow.Position.Y", JsonValue.CreateNumberValue(appWindow.Position.Y)); + jsonWindowPlacement.SetNamedValue("appWindow.Size.Width", JsonValue.CreateNumberValue(appWindow.Size.Width)); + jsonWindowPlacement.SetNamedValue("appWindow.Size.Height", JsonValue.CreateNumberValue(appWindow.Size.Height)); + } + + /// + /// Event that is will prevent the app from closing if the "save file" flag is active + /// + public void Window_Closed(object sender, WindowEventArgs args) + { + // Save window placement + SaveWindowPlacementFile(settingsFolder, windowPlacementFile); + } + } +} diff --git a/src/modules/registrypreview/RegistryPreview/MainWindow.Utilities.cs b/src/modules/registrypreview/RegistryPreview/MainWindow.Utilities.cs new file mode 100644 index 0000000000..9104969280 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview/MainWindow.Utilities.cs @@ -0,0 +1,95 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Diagnostics; +using System.IO; +using System.Threading.Tasks; +using Windows.Storage; +using WinUIEx; + +namespace RegistryPreview +{ + public sealed partial class MainWindow : WindowEx + { + private void OpenWindowPlacementFile(string path, string filename) + { + string fileContents = string.Empty; + string storageFile = Path.Combine(path, filename); + if (File.Exists(storageFile)) + { + try + { + StreamReader reader = new StreamReader(storageFile); + fileContents = reader.ReadToEnd(); + reader.Close(); + } + catch + { + // set up default JSON blob + fileContents = "{ }"; + } + } + else + { + Task.Run(() => SaveWindowPlacementFile(path, filename)).GetAwaiter().GetResult(); + } + + try + { + jsonWindowPlacement = Windows.Data.Json.JsonObject.Parse(fileContents); + } + catch + { + // set up default JSON blob + fileContents = "{ }"; + jsonWindowPlacement = Windows.Data.Json.JsonObject.Parse(fileContents); + } + } + + /// + /// Save the window placement JSON blob out to a local file + /// + private async void SaveWindowPlacementFile(string path, string filename) + { + StorageFolder storageFolder = null; + StorageFile storageFile = null; + string fileContents = string.Empty; + + try + { + storageFolder = await StorageFolder.GetFolderFromPathAsync(path); + } + catch (FileNotFoundException ex) + { + Debug.WriteLine(ex.Message); + Directory.CreateDirectory(path); + storageFolder = await StorageFolder.GetFolderFromPathAsync(path); + } + + try + { + storageFile = await storageFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists); + } + catch (FileNotFoundException ex) + { + Debug.WriteLine(ex.Message); + storageFile = await storageFolder.CreateFileAsync(filename); + } + + try + { + if (jsonWindowPlacement != null) + { + fileContents = jsonWindowPlacement.Stringify(); + await Windows.Storage.FileIO.WriteTextAsync(storageFile, fileContents); + } + } + catch (Exception ex) + { + Debug.WriteLine(ex.Message); + } + } + } +} diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj b/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj new file mode 100644 index 0000000000..26623d6ee3 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreview.csproj @@ -0,0 +1,91 @@ + + + + WinExe + net8.0-windows10.0.20348.0 + 10.0.19041.0 + 10.0.19041.0 + RegistryPreview + app.manifest + x86;x64;ARM64 + win-x64;win-arm64 + true + true + true + None + false + false + true + true + ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps + PowerToys.RegistryPreview + Assets\RegistryPreview\RegistryPreview.ico + + PowerToys.RegistryPreview.pri + + + + + + + + + + + + + + + + + win-x64 + + + win-arm64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + \ No newline at end of file diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/App.xaml b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml similarity index 91% rename from src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/App.xaml rename to src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml index 9ccb7447ef..7c2836890c 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/App.xaml +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/App.xaml @@ -1,4 +1,5 @@ - + @@ -20,6 +19,8 @@ namespace RegistryPreview { /// /// Initializes a new instance of the class. + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). /// public App() { @@ -27,8 +28,7 @@ namespace RegistryPreview } /// - /// Invoked when the application is launched normally by the end user. Other entry points - /// will be used such as when the application is launched to open a specific file. + /// Invoked when the application is launched. /// /// Details about the launch request and process. protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args) diff --git a/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml new file mode 100644 index 0000000000..95ab0e4331 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/MainWindow.xaml.cs b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml.cs similarity index 70% rename from src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/MainWindow.xaml.cs rename to src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml.cs index 37e455c503..2cbc80b22c 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/MainWindow.xaml.cs +++ b/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml.cs @@ -1,16 +1,14 @@ -// Copyright (c) Microsoft Corporation +// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; -using System.Collections.Generic; -using System.IO; using ManagedCommon; using Microsoft.UI; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Media; -using Microsoft.Windows.ApplicationModel.Resources; +using RegistryPreviewUILib; using Windows.Data.Json; using Windows.Graphics; using WinUIEx; @@ -20,39 +18,31 @@ namespace RegistryPreview public sealed partial class MainWindow : WindowEx { // Const values - private const string REGISTRYHEADER4 = "regedit4"; - private const string REGISTRYHEADER5 = "windows registry editor version 5.00"; private const string APPNAME = "RegistryPreview"; - private const string KEYIMAGE = "ms-appx:///Assets/RegistryPreview/folder32.png"; - private const string DELETEDKEYIMAGE = "ms-appx:///Assets/RegistryPreview/deleted-folder32.png"; - private const string ERRORIMAGE = "ms-appx:///Assets/RegistryPreview/error32.png"; // private members private Microsoft.UI.Windowing.AppWindow appWindow; - private ResourceLoader resourceLoader; - private bool visualTreeReady; - private Dictionary mapRegistryKeys; - private List listRegistryValues; private JsonObject jsonWindowPlacement; private string settingsFolder = string.Empty; private string windowPlacementFile = "app-placement.json"; + private RegistryPreviewMainPage MainPage { get; } + internal MainWindow() { this.InitializeComponent(); - // Initialize the string table - resourceLoader = ResourceLoaderInstance.ResourceLoader; - // Open settings file; this moved to after the window tweak because it gives the window time to start up settingsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @"\Microsoft\PowerToys\" + APPNAME; OpenWindowPlacementFile(settingsFolder, windowPlacementFile); // Update the Win32 looking window with the correct icon (and grab the appWindow handle for later) IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this); - WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle); + Microsoft.UI.WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle); appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId); - appWindow.SetIcon("Assets\\RegistryPreview\\app.ico"); + appWindow.SetIcon("Assets\\RegistryPreview\\RegistryPreview.ico"); + + // TODO(stefan) appWindow.Closing += AppWindow_Closing; Activated += MainWindow_Activated; @@ -92,12 +82,7 @@ namespace RegistryPreview } } - // Update Toolbar - if ((App.AppFilename == null) || (File.Exists(App.AppFilename) != true)) - { - UpdateToolBarAndUI(false); - UpdateWindowTitle(resourceLoader.GetString("FileNotFound")); - } + MainPage = new RegistryPreviewMainPage(this, this.UpdateWindowTitle, App.AppFilename); WindowHelpers.BringToForeground(windowHandle); } @@ -107,12 +92,44 @@ namespace RegistryPreview if (args.WindowActivationState == WindowActivationState.Deactivated) { titleBarText.Foreground = - (SolidColorBrush)App.Current.Resources["WindowCaptionForegroundDisabled"]; + (SolidColorBrush)Application.Current.Resources["WindowCaptionForegroundDisabled"]; } else { titleBarText.Foreground = - (SolidColorBrush)App.Current.Resources["WindowCaptionForeground"]; + (SolidColorBrush)Application.Current.Resources["WindowCaptionForeground"]; + } + } + + private void Grid_Loaded(object sender, RoutedEventArgs e) + { + MainGrid.Children.Add(MainPage); + Grid.SetRow(MainPage, 1); + } + + public void UpdateWindowTitle(string title) + { + string filename = title; + + if (string.IsNullOrEmpty(filename)) + { + titleBarText.Text = APPNAME; + appWindow.Title = APPNAME; + } + else + { + string[] file = filename.Split('\\'); + if (file.Length > 0) + { + titleBarText.Text = file[file.Length - 1] + " - " + APPNAME; + } + else + { + titleBarText.Text = filename + " - " + APPNAME; + } + + // Continue to update the window's title, after updating the custom title bar + appWindow.Title = titleBarText.Text; } } } diff --git a/src/modules/registrypreview/RegistryPreview/Strings/en-us/Resources.resw b/src/modules/registrypreview/RegistryPreview/Strings/en-us/Resources.resw new file mode 100644 index 0000000000..61550769a3 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview/Strings/en-us/Resources.resw @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/src/modules/registrypreview/RegistryPreview/app.manifest b/src/modules/registrypreview/RegistryPreview/app.manifest new file mode 100644 index 0000000000..c3f3db0141 --- /dev/null +++ b/src/modules/registrypreview/RegistryPreview/app.manifest @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + PerMonitorV2 + + + \ No newline at end of file diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj b/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj deleted file mode 100644 index 5c38551b43..0000000000 --- a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj +++ /dev/null @@ -1,84 +0,0 @@ - - - - WinExe - net8.0-windows10.0.20348.0 - 10.0.19041.0 - 10.0.19041.0 - x86;x64;arm64 - ..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps - true - False - Assets\RegistryPreview\app.ico - app.manifest - true - false - false - true - None - true - true - $(AssemblyName) - PowerToys.RegistryPreview - PowerToys.RegistryPreview - PowerToys RegistryPreview - RegistryPreview - true - true - - PowerToys.RegistryPreview.pri - - - - - - - - - - - - win-x64 - - - win-arm64 - - - - - - - - - PowerToys.GPOWrapper - $(OutDir) - false - - - - - - - - - - - - - - - - - - - - - - Never - - - Never - - - - diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/MainWindow.xaml b/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/MainWindow.xaml deleted file mode 100644 index 3bce0037d6..0000000000 --- a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewXAML/MainWindow.xaml +++ /dev/null @@ -1,310 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/RegistryPreview.ico b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/RegistryPreview.ico new file mode 100644 index 0000000000..0b83ebb9fd Binary files /dev/null and b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/RegistryPreview.ico differ diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/data32.png b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/data32.png similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/data32.png rename to src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/data32.png diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/deleted-folder32.png b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/deleted-folder32.png similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/deleted-folder32.png rename to src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/deleted-folder32.png diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/deleted-value32.png b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/deleted-value32.png similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/deleted-value32.png rename to src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/deleted-value32.png diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/error32.png b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/error32.png similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/error32.png rename to src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/error32.png diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/folder32.png b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/folder32.png similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/folder32.png rename to src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/folder32.png diff --git a/src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/string32.png b/src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/string32.png similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Assets/RegistryPreview/string32.png rename to src/modules/registrypreview/RegistryPreviewUILib/Assets/RegistryPreview/string32.png diff --git a/src/modules/registrypreview/RegistryPreviewUI/FileName.cs b/src/modules/registrypreview/RegistryPreviewUILib/FileName.cs similarity index 97% rename from src/modules/registrypreview/RegistryPreviewUI/FileName.cs rename to src/modules/registrypreview/RegistryPreviewUILib/FileName.cs index 7464fff039..119ae7ea84 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/FileName.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/FileName.cs @@ -5,7 +5,7 @@ using System; using System.Runtime.InteropServices; -namespace RegistryPreview +namespace RegistryPreviewUILib { // Workaround for File Pickers that don't work while running as admin, per: // https://github.com/microsoft/WindowsAppSDK/issues/2504 diff --git a/src/modules/registrypreview/RegistryPreviewUI/OpenFileName.cs b/src/modules/registrypreview/RegistryPreviewUILib/OpenFileName.cs similarity index 97% rename from src/modules/registrypreview/RegistryPreviewUI/OpenFileName.cs rename to src/modules/registrypreview/RegistryPreviewUILib/OpenFileName.cs index 77f3354886..23c46983bd 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/OpenFileName.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/OpenFileName.cs @@ -5,7 +5,7 @@ using System; using System.Runtime.InteropServices; -namespace RegistryPreview +namespace RegistryPreviewUILib { // Workaround for File Pickers that don't work while running as admin, per: // https://github.com/microsoft/WindowsAppSDK/issues/2504 diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryKey.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs similarity index 96% rename from src/modules/registrypreview/RegistryPreviewUI/RegistryKey.xaml.cs rename to src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs index 343966fa3d..4466000059 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/RegistryKey.xaml.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs @@ -2,7 +2,7 @@ // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace RegistryPreview +namespace RegistryPreviewUILib { /// /// Class representing an each item in the tree view, each one a Registry Key; diff --git a/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs similarity index 88% rename from src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs rename to src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs index dadcdd2a0e..74726a651a 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Events.cs @@ -13,33 +13,17 @@ using CommunityToolkit.WinUI.UI.Controls; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Microsoft.UI.Xaml.Data; -using Microsoft.UI.Xaml.Media; -using Windows.Data.Json; using Windows.Foundation.Metadata; using Windows.Storage; -using Windows.Storage.Pickers; -using WinRT.Interop; -using WinUIEx; -namespace RegistryPreview +namespace RegistryPreviewUILib { - public sealed partial class MainWindow : WindowEx + public sealed partial class RegistryPreviewMainPage : Page { - /// - /// Event handler to grab the main window's size and position before it closes - /// - private void AppWindow_Closing(Microsoft.UI.Windowing.AppWindow sender, Microsoft.UI.Windowing.AppWindowClosingEventArgs args) - { - jsonWindowPlacement.SetNamedValue("appWindow.Position.X", JsonValue.CreateNumberValue(appWindow.Position.X)); - jsonWindowPlacement.SetNamedValue("appWindow.Position.Y", JsonValue.CreateNumberValue(appWindow.Position.Y)); - jsonWindowPlacement.SetNamedValue("appWindow.Size.Width", JsonValue.CreateNumberValue(appWindow.Size.Width)); - jsonWindowPlacement.SetNamedValue("appWindow.Size.Height", JsonValue.CreateNumberValue(appWindow.Size.Height)); - } - /// /// Event that is will prevent the app from closing if the "save file" flag is active /// - public void Window_Closed(object sender, WindowEventArgs args) + public void MainWindow_Closed(object sender, WindowEventArgs args) { // Only block closing if the REG file has been edited but not yet saved if (saveButton.IsEnabled) @@ -69,13 +53,10 @@ namespace RegistryPreview DispatcherQueue.TryEnqueue(async () => { await Task.Delay(100); - App.Current.Exit(); + Application.Current.Exit(); }); return; } - - // Save window placement - SaveWindowPlacementFile(settingsFolder, windowPlacementFile); } /// @@ -87,20 +68,20 @@ namespace RegistryPreview visualTreeReady = true; // Check to see if the REG file was opened and parsed successfully - if (OpenRegistryFile(App.AppFilename) == false) + if (OpenRegistryFile(_appFileName) == false) { - if (File.Exists(App.AppFilename)) + if (File.Exists(_appFileName)) { // Allow Refresh and Edit to be enabled because a broken Reg file might be fixable UpdateToolBarAndUI(false, true, true); - UpdateWindowTitle(resourceLoader.GetString("InvalidRegistryFileTitle")); + _updateWindowTitleFunction(resourceLoader.GetString("InvalidRegistryFileTitle")); textBox.TextChanged += TextBox_TextChanged; return; } else { UpdateToolBarAndUI(false, false, false); - UpdateWindowTitle(); + _updateWindowTitleFunction(string.Empty); } } else @@ -155,7 +136,7 @@ namespace RegistryPreview // Pull in a new REG file - we have to use the direct Win32 method because FileOpenPicker crashes when it's // called while running as admin - IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this); + IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow); string filename = OpenFilePicker.ShowDialog( windowHandle, resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0', @@ -173,8 +154,8 @@ namespace RegistryPreview // mute the TextChanged handler to make for clean UI textBox.TextChanged -= TextBox_TextChanged; - App.AppFilename = storageFile.Path; - UpdateToolBarAndUI(OpenRegistryFile(App.AppFilename)); + _appFileName = storageFile.Path; + UpdateToolBarAndUI(OpenRegistryFile(_appFileName)); // disable the Save button as it's a new file saveButton.IsEnabled = false; @@ -199,7 +180,7 @@ namespace RegistryPreview { // Save out a new REG file and then open it - we have to use the direct Win32 method because FileOpenPicker crashes when it's // called while running as admin - IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(this); + IntPtr windowHandle = WinRT.Interop.WindowNative.GetWindowHandle(_mainWindow); string filename = SaveFilePicker.ShowDialog( windowHandle, resourceLoader.GetString("SuggestFileName"), @@ -211,9 +192,9 @@ namespace RegistryPreview return; } - App.AppFilename = filename; + _appFileName = filename; SaveFile(); - UpdateToolBarAndUI(OpenRegistryFile(App.AppFilename)); + UpdateToolBarAndUI(OpenRegistryFile(_appFileName)); } /// @@ -225,7 +206,7 @@ namespace RegistryPreview textBox.TextChanged -= TextBox_TextChanged; // reload the current Registry file and update the toolbar accordingly. - UpdateToolBarAndUI(OpenRegistryFile(App.AppFilename), true, true); + UpdateToolBarAndUI(OpenRegistryFile(_appFileName), true, true); saveButton.IsEnabled = false; @@ -305,7 +286,7 @@ namespace RegistryPreview } // pass in the filename so we can edit the current file - OpenRegistryEditor(App.AppFilename); + OpenRegistryEditor(_appFileName); } /// @@ -315,7 +296,7 @@ namespace RegistryPreview { // use the REG file's filename and verb so we can respect the selected editor Process process = new Process(); - process.StartInfo.FileName = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", App.AppFilename); + process.StartInfo.FileName = string.Format(CultureInfo.InvariantCulture, "\"{0}\"", _appFileName); process.StartInfo.Verb = "Edit"; process.StartInfo.UseShellExecute = true; diff --git a/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs similarity index 91% rename from src/modules/registrypreview/RegistryPreviewUI/MainWindow.Utilities.cs rename to src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs index aada6f1b5e..a738b8cc27 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Utilities.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs @@ -11,18 +11,17 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; -using System.Threading.Tasks; using Microsoft.UI.Input; using Microsoft.UI.Xaml; using Microsoft.UI.Xaml.Controls; using Windows.Foundation.Metadata; -using Windows.Storage; -using WinUIEx; -namespace RegistryPreview +namespace RegistryPreviewUILib { - public sealed partial class MainWindow : WindowEx + public sealed partial class RegistryPreviewMainPage : Page { + public delegate void UpdateWindowTitleFunction(string title); + /// /// Method that opens and processes the passed in file name; expected to be an absolute path and a first time open /// @@ -34,7 +33,7 @@ namespace RegistryPreview long fileLength = new System.IO.FileInfo(filename).Length; if (fileLength > 10485760) { - ShowMessageBox(resourceLoader.GetString("LargeRegistryFileTitle"), App.AppFilename + resourceLoader.GetString("LargeRegistryFile"), resourceLoader.GetString("OkButtonText")); + ShowMessageBox(resourceLoader.GetString("LargeRegistryFileTitle"), _appFileName + resourceLoader.GetString("LargeRegistryFile"), resourceLoader.GetString("OkButtonText")); ChangeCursor(gridPreview, false); return false; } @@ -53,7 +52,7 @@ namespace RegistryPreview ClearTable(); // update the current window's title with the current filename - UpdateWindowTitle(filename); + _updateWindowTitleFunction(filename); // Load in the whole file in one call and plop it all into textBox FileStream fileStream = null; @@ -204,7 +203,7 @@ namespace RegistryPreview case REGISTRYHEADER5: break; default: - ShowMessageBox(APPNAME, App.AppFilename + resourceLoader.GetString("InvalidRegistryFile"), resourceLoader.GetString("OkButtonText")); + ShowMessageBox(APPNAME, _appFileName + resourceLoader.GetString("InvalidRegistryFile"), resourceLoader.GetString("OkButtonText")); ChangeCursor(gridPreview, false); return false; } @@ -600,7 +599,7 @@ namespace RegistryPreview { AddTextToTree(resourceLoader.GetString("NoNodesFoundInFile"), ERRORIMAGE); - // ShowMessageBox(APPNAME, App.AppFilename + resourceLoader.GetString("InvalidRegistryFile"), resourceLoader.GetString("OkButtonText")); + // ShowMessageBox(APPNAME, _appFileName + resourceLoader.GetString("InvalidRegistryFile"), resourceLoader.GetString("OkButtonText")); } ChangeCursor(gridPreview, false); @@ -614,7 +613,7 @@ namespace RegistryPreview // last check, to see if anything got parsed! if (treeView.RootNodes.Count <= 0) { - ShowMessageBox(APPNAME, App.AppFilename + resourceLoader.GetString("InvalidRegistryFile"), resourceLoader.GetString("OkButtonText")); + ShowMessageBox(APPNAME, _appFileName + resourceLoader.GetString("InvalidRegistryFile"), resourceLoader.GetString("OkButtonText")); ChangeCursor(gridPreview, false); return false; } @@ -646,34 +645,6 @@ namespace RegistryPreview registryKey.Tag = arrayList; } - /// - /// Adds the REG file that's being currently being viewed to the app's title bar - /// - private void UpdateWindowTitle(string filename) - { - string[] file = filename.Split('\\'); - if (file.Length > 0) - { - titleBarText.Text = file[file.Length - 1] + " - " + APPNAME; - } - else - { - titleBarText.Text = filename + " - " + APPNAME; - } - - // Continue to update the window's title, after updating the custom title bar - appWindow.Title = titleBarText.Text; - } - - /// - /// No REG file was opened, so leave the app's title bar alone - /// - private void UpdateWindowTitle() - { - titleBarText.Text = APPNAME; - appWindow.Title = APPNAME; - } - /// /// Helper method that assumes everything is enabled/disabled together /// @@ -861,7 +832,7 @@ namespace RegistryPreview } // if we got here, we should try to close again - App.Current.Exit(); + Application.Current.Exit(); } /// @@ -939,7 +910,7 @@ namespace RegistryPreview fileStreamOptions.Share = FileShare.Write; fileStreamOptions.Mode = FileMode.Create; - fileStream = new FileStream(App.AppFilename, fileStreamOptions); + fileStream = new FileStream(_appFileName, fileStreamOptions); StreamWriter streamWriter = new StreamWriter(fileStream, System.Text.Encoding.Unicode); // if we get here, the file is open and writable so dump the whole contents of textBox @@ -980,85 +951,6 @@ namespace RegistryPreview ChangeCursor(gridPreview, false); } - private void OpenWindowPlacementFile(string path, string filename) - { - string fileContents = string.Empty; - string storageFile = Path.Combine(path, filename); - if (File.Exists(storageFile)) - { - try - { - StreamReader reader = new StreamReader(storageFile); - fileContents = reader.ReadToEnd(); - reader.Close(); - } - catch - { - // set up default JSON blob - fileContents = "{ }"; - } - } - else - { - Task.Run(() => SaveWindowPlacementFile(path, filename)).GetAwaiter().GetResult(); - } - - try - { - jsonWindowPlacement = Windows.Data.Json.JsonObject.Parse(fileContents); - } - catch - { - // set up default JSON blob - fileContents = "{ }"; - jsonWindowPlacement = Windows.Data.Json.JsonObject.Parse(fileContents); - } - } - - /// - /// Save the window placement JSON blob out to a local file - /// - private async void SaveWindowPlacementFile(string path, string filename) - { - StorageFolder storageFolder = null; - StorageFile storageFile = null; - string fileContents = string.Empty; - - try - { - storageFolder = await StorageFolder.GetFolderFromPathAsync(path); - } - catch (FileNotFoundException ex) - { - Debug.WriteLine(ex.Message); - Directory.CreateDirectory(path); - storageFolder = await StorageFolder.GetFolderFromPathAsync(path); - } - - try - { - storageFile = await storageFolder.CreateFileAsync(filename, CreationCollisionOption.OpenIfExists); - } - catch (FileNotFoundException ex) - { - Debug.WriteLine(ex.Message); - storageFile = await storageFolder.CreateFileAsync(filename); - } - - try - { - if (jsonWindowPlacement != null) - { - fileContents = jsonWindowPlacement.Stringify(); - await Windows.Storage.FileIO.WriteTextAsync(storageFile, fileContents); - } - } - catch (Exception ex) - { - Debug.WriteLine(ex.Message); - } - } - /// /// Rip the first and last character off a string, /// checking that the string is at least 2 characters long to avoid errors diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml new file mode 100644 index 0000000000..f5e0c6ee1a --- /dev/null +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml @@ -0,0 +1,270 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs new file mode 100644 index 0000000000..0813a6748d --- /dev/null +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs @@ -0,0 +1,55 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.IO; +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.Windows.ApplicationModel.Resources; + +namespace RegistryPreviewUILib +{ + public sealed partial class RegistryPreviewMainPage : Page + { + // Const values + private const string REGISTRYHEADER4 = "regedit4"; + private const string REGISTRYHEADER5 = "windows registry editor version 5.00"; + private const string APPNAME = "RegistryPreview"; + private const string KEYIMAGE = "ms-appx:///Assets/RegistryPreview/folder32.png"; + private const string DELETEDKEYIMAGE = "ms-appx:///Assets/RegistryPreview/deleted-folder32.png"; + private const string ERRORIMAGE = "ms-appx:///Assets/RegistryPreview/error32.png"; + + // private members + private ResourceLoader resourceLoader; + private bool visualTreeReady; + private Dictionary mapRegistryKeys; + private List listRegistryValues; + + private UpdateWindowTitleFunction _updateWindowTitleFunction; + private string _appFileName; + private Window _mainWindow; + + public RegistryPreviewMainPage(Window mainWindow, UpdateWindowTitleFunction updateWindowTitleFunction, string appFilename) + { + // TODO (stefan): check ctor + this.InitializeComponent(); + + _mainWindow = mainWindow; + _updateWindowTitleFunction = updateWindowTitleFunction; + _appFileName = appFilename; + + _mainWindow.Closed += MainWindow_Closed; + + // Initialize the string table + resourceLoader = ResourceLoaderInstance.ResourceLoader; + + // Update Toolbar + if ((_appFileName == null) || (File.Exists(_appFileName) != true)) + { + UpdateToolBarAndUI(false); + _updateWindowTitleFunction(resourceLoader.GetString("FileNotFound")); + } + } + } +} diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj new file mode 100644 index 0000000000..9d20a7c64d --- /dev/null +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewUILib.csproj @@ -0,0 +1,69 @@ + + + + Library + net8.0-windows10.0.20348 + RegistryPreviewUILib + true + true + false + false + PowerToys.RegistryPreviewUILib + + PowerToys.RegistryPreviewUILib.pri + + true + true + + + + + + + + + + + + + + + + + + + + + true + DEBUG;TRACE + full + prompt + 4 + false + + + + TRACE + true + pdbonly + prompt + 4 + + + + + + + + + + + + + + + + Always + + + diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryValue.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs similarity index 98% rename from src/modules/registrypreview/RegistryPreviewUI/RegistryValue.xaml.cs rename to src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs index 161e9cbedd..3e0d16c932 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/RegistryValue.xaml.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs @@ -4,7 +4,7 @@ using System; -namespace RegistryPreview +namespace RegistryPreviewUILib { /// /// Class representing an each item in the list view, each one a Registry Value. diff --git a/src/modules/Hosts/Hosts/Helpers/ResourceLoaderInstance.cs b/src/modules/registrypreview/RegistryPreviewUILib/ResourceLoaderInstance.cs similarity index 77% rename from src/modules/Hosts/Hosts/Helpers/ResourceLoaderInstance.cs rename to src/modules/registrypreview/RegistryPreviewUILib/ResourceLoaderInstance.cs index c7339998a8..bf65224b8d 100644 --- a/src/modules/Hosts/Hosts/Helpers/ResourceLoaderInstance.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/ResourceLoaderInstance.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using Microsoft.Windows.ApplicationModel.Resources; -namespace Hosts.Helpers +namespace RegistryPreviewUILib { internal static class ResourceLoaderInstance { @@ -11,7 +11,7 @@ namespace Hosts.Helpers static ResourceLoaderInstance() { - ResourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("PowerToys.Hosts.pri"); + ResourceLoader = new Microsoft.Windows.ApplicationModel.Resources.ResourceLoader("PowerToys.RegistryPreviewUILib.pri", "PowerToys.RegistryPreviewUILib/Resources"); } } } diff --git a/src/modules/registrypreview/RegistryPreviewUI/SaveFileName.cs b/src/modules/registrypreview/RegistryPreviewUILib/SaveFileName.cs similarity index 98% rename from src/modules/registrypreview/RegistryPreviewUI/SaveFileName.cs rename to src/modules/registrypreview/RegistryPreviewUILib/SaveFileName.cs index ce29f48d1d..d019d29c6b 100644 --- a/src/modules/registrypreview/RegistryPreviewUI/SaveFileName.cs +++ b/src/modules/registrypreview/RegistryPreviewUILib/SaveFileName.cs @@ -5,7 +5,7 @@ using System; using System.Runtime.InteropServices; -namespace RegistryPreview +namespace RegistryPreviewUILib { // Workaround for File Pickers that don't work while running as admin, per: // https://github.com/microsoft/WindowsAppSDK/issues/2504 diff --git a/src/modules/registrypreview/RegistryPreviewUI/Strings/en-US/Resources.resw b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/Strings/en-US/Resources.resw rename to src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw diff --git a/src/modules/registrypreview/RegistryPreviewUI/app.manifest b/src/modules/registrypreview/RegistryPreviewUILib/app.manifest similarity index 100% rename from src/modules/registrypreview/RegistryPreviewUI/app.manifest rename to src/modules/registrypreview/RegistryPreviewUILib/app.manifest