[EnvVar][Hosts][RegPrev]Decouple and refactor to make it "packable" as nuget package (#32604)
* WIP Hosts - remove deps * Add consumer app * Move App and MainWindow to Consumer app. Make Hosts dll * Try consume it * Fix errors * Make it work with custom build targets * Dependency injection Refactor Explicit page creation Wire missing dependencies * Fix installer * Remove unneeded stuff * Fix build again * Extract UI and logic from MainWindow to RegistryPreviewMainPage * Convert to lib Change namespace to RegistryPreviewUILib Remove PT deps * Add exe app and move App.xaml and MainWindow.xaml * Consume the lib * Update Hosts package creation * Fix RegistryPreview package creation * Rename RegistryPreviewUI back to RegistryPreview * Back to consuming lib * Ship icons and assets in nuget packages * Rename to EnvironmentVariablesUILib and convert to lib * Add app and consume * Telemetry * GPO * nuget * Rename HostsPackageConsumer to Hosts and Hosts lib to HostsUILib * Assets cleanup * nuget struct * v0 * assets * [Hosts] Re-add AppList to Lib Assets, [RegPrev] Copy lib assets to out dir * Sign UI dlls * Revert WinUIEx bump * Cleanup * Align deps * version exception dll * Fix RegistryPreview crashes * XAML format * XAML format 2 * Pack .pri files in lib/ dir --------- Co-authored-by: Darshak Bhatti <dabhatti@microsoft.com>
|
Before Width: | Height: | Size: 135 KiB After Width: | Height: | Size: 135 KiB |
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Event handler to grab the main window's size and position before it closes
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event that is will prevent the app from closing if the "save file" flag is active
|
||||
/// </summary>
|
||||
public void Window_Closed(object sender, WindowEventArgs args)
|
||||
{
|
||||
// Save window placement
|
||||
SaveWindowPlacementFile(settingsFolder, windowPlacementFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the window placement JSON blob out to a local file
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<RootNamespace>RegistryPreview</RootNamespace>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<Platforms>x86;x64;ARM64</Platforms>
|
||||
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnableMsixTooling>true</EnableMsixTooling>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps</OutputPath>
|
||||
<AssemblyName>PowerToys.RegistryPreview</AssemblyName>
|
||||
<ApplicationIcon>Assets\RegistryPreview\RegistryPreview.ico</ApplicationIcon>
|
||||
<!-- MRT from windows app sdk will search for a pri file with the same name of the module before defaulting to resources.pri -->
|
||||
<ProjectPriFileName>PowerToys.RegistryPreview.pri</ProjectPriFileName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Remove="RegistryPreviewXAML\App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="RegistryPreviewXAML\App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="RegistryPreviewXAML\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'">
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
|
||||
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
<!--
|
||||
Defining the "Msix" ProjectCapability here allows the Single-project MSIX Packaging
|
||||
Tools extension to be activated for this project even if the Windows App SDK Nuget
|
||||
package has not yet been restored.
|
||||
-->
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<!-- HACK: Common.UI is referenced, even if it is not used, to force dll versions to be the same as in other projects that use it. It's still unclear why this is the case, but this is need for flattening the install directory. -->
|
||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||
<ProjectReference Include="..\RegistryPreviewUILib\RegistryPreviewUILib.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="CopyPRIFileToOutputDir" AfterTargets="Build">
|
||||
<Message Text="Executing CopyDLLs task" Importance="High" />
|
||||
<ItemGroup>
|
||||
<PRIFile Include="$(OutDir)**\PowerToys.RegistryPreviewUILib.pri" />
|
||||
</ItemGroup>
|
||||
|
||||
<Copy SourceFiles="@(PRIFile)" DestinationFolder="$(OutDir)" />
|
||||
|
||||
<Message Text="Copied build files" Importance="High" />
|
||||
</Target>
|
||||
|
||||
<!--
|
||||
Defining the "HasPackageAndPublishMenuAddedByProject" property here allows the Solution
|
||||
Explorer "Package and Publish" context menu entry to be enabled for this project even if
|
||||
the Windows App SDK Nuget package has not yet been restored.
|
||||
-->
|
||||
<PropertyGroup Condition="'$(DisableHasPackageAndPublishMenuAddedByProject)'!='true' and '$(EnableMsixTooling)'=='true'">
|
||||
<HasPackageAndPublishMenu>true</HasPackageAndPublishMenu>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,4 +1,5 @@
|
||||
<Application
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<Application
|
||||
x:Class="RegistryPreview.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
@@ -3,14 +3,13 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Web;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
using LaunchActivatedEventArgs = Windows.ApplicationModel.Activation.LaunchActivatedEventArgs;
|
||||
|
||||
// To learn more about WinUI, the WinUI project structure,
|
||||
// and more about our project templates, see: http://aka.ms/winui-project-info.
|
||||
namespace RegistryPreview
|
||||
{
|
||||
/// <summary>
|
||||
@@ -20,6 +19,8 @@ namespace RegistryPreview
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="App"/> 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().
|
||||
/// </summary>
|
||||
public App()
|
||||
{
|
||||
@@ -27,8 +28,7 @@ namespace RegistryPreview
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
/// <param name="args">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
|
||||
@@ -0,0 +1,52 @@
|
||||
<winuiex:WindowEx
|
||||
x:Class="RegistryPreview.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
MinWidth="480"
|
||||
MinHeight="320"
|
||||
Closed="Window_Closed"
|
||||
mc:Ignorable="d">
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
|
||||
<Grid x:Name="MainGrid" Loaded="Grid_Loaded">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid
|
||||
x:Name="titleBar"
|
||||
Grid.Row="0"
|
||||
Height="32"
|
||||
Margin="16,0"
|
||||
ColumnSpacing="16"
|
||||
IsHitTestVisible="True">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!--<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>-->
|
||||
<ColumnDefinition x:Name="IconColumn" Width="Auto" />
|
||||
<ColumnDefinition x:Name="TitleColumn" Width="Auto" />
|
||||
<!--<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Source="../Assets/RegistryPreview/RegistryPreview.ico" />
|
||||
<TextBlock
|
||||
x:Name="titleBarText"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding ApplicationTitle}" />
|
||||
</Grid>
|
||||
|
||||
</Grid>
|
||||
</winuiex:WindowEx>
|
||||
@@ -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<string, TreeViewNode> mapRegistryKeys;
|
||||
private List<RegistryValue> 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root"
|
||||
xmlns=""
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
19
src/modules/registrypreview/RegistryPreview/app.manifest
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
<assemblyIdentity version="1.0.0.0" name="RegistryPreview.app"/>
|
||||
|
||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||
<application>
|
||||
<!-- The ID below informs the system that this application is compatible with OS features first introduced in Windows 10.
|
||||
It is necessary to support features in unpackaged applications, for example the custom titlebar implementation.
|
||||
For more info see https://docs.microsoft.com/windows/apps/windows-app-sdk/use-windows-app-sdk-run-time#declare-os-compatibility-in-your-application-manifest -->
|
||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||
</application>
|
||||
</compatibility>
|
||||
|
||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<windowsSettings>
|
||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||
</windowsSettings>
|
||||
</application>
|
||||
</assembly>
|
||||
@@ -1,84 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Project="..\..\..\Version.props" />
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows10.0.20348.0</TargetFramework>
|
||||
<TargetPlatformMinVersion>10.0.19041.0</TargetPlatformMinVersion>
|
||||
<SupportedOSPlatformVersion>10.0.19041.0</SupportedOSPlatformVersion>
|
||||
<Platforms>x86;x64;arm64</Platforms>
|
||||
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps</OutputPath>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<UseWindowsForms>False</UseWindowsForms>
|
||||
<ApplicationIcon>Assets\RegistryPreview\app.ico</ApplicationIcon>
|
||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
<WindowsPackageType>None</WindowsPackageType>
|
||||
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
|
||||
<SelfContained>true</SelfContained>
|
||||
<Product>$(AssemblyName)</Product>
|
||||
<AssemblyName>PowerToys.RegistryPreview</AssemblyName>
|
||||
<AssemblyTitle>PowerToys.RegistryPreview</AssemblyTitle>
|
||||
<AssemblyDescription>PowerToys RegistryPreview</AssemblyDescription>
|
||||
<RootNamespace>RegistryPreview</RootNamespace>
|
||||
<DisableWinExeOutputInference>true</DisableWinExeOutputInference>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<!-- MRT from windows app sdk will search for a pri file with the same name of the module before defaulting to resources.pri -->
|
||||
<ProjectPriFileName>PowerToys.RegistryPreview.pri</ProjectPriFileName>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Remove="RegistryPreviewXAML\App.xaml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ApplicationDefinition Include="RegistryPreviewXAML\App.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||
<PropertyGroup Condition="'$(Platform)'=='x64'">
|
||||
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Platform)'=='ARM64'">
|
||||
<RuntimeIdentifier>win-arm64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Assets\RegistryPreview\app.ico" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||
<PropertyGroup>
|
||||
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
|
||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
||||
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Update="Assets\RegistryPreview\data32.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Content>
|
||||
<Content Update="Assets\RegistryPreview\string32.png">
|
||||
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
<!--TargetFramework>net6.0-windows10.0.19041.0</TargetFramework-->
|
||||
@@ -1,310 +0,0 @@
|
||||
<winuiex:WindowEx
|
||||
x:Class="RegistryPreview.MainWindow"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
xmlns:winuiex="using:WinUIEx"
|
||||
MinWidth="480"
|
||||
MinHeight="320"
|
||||
Closed="Window_Closed"
|
||||
mc:Ignorable="d">
|
||||
<Window.SystemBackdrop>
|
||||
<MicaBackdrop />
|
||||
</Window.SystemBackdrop>
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid
|
||||
x:Name="titleBar"
|
||||
Grid.Row="0"
|
||||
Height="32"
|
||||
Margin="16,0"
|
||||
ColumnSpacing="16"
|
||||
IsHitTestVisible="True">
|
||||
<Grid.ColumnDefinitions>
|
||||
<!--<ColumnDefinition x:Name="LeftPaddingColumn" Width="0"/>-->
|
||||
<ColumnDefinition x:Name="IconColumn" Width="Auto" />
|
||||
<ColumnDefinition x:Name="TitleColumn" Width="Auto" />
|
||||
<!--<ColumnDefinition x:Name="RightPaddingColumn" Width="0"/>-->
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Grid.Column="0"
|
||||
Width="16"
|
||||
Height="16"
|
||||
VerticalAlignment="Center"
|
||||
Source="../Assets/RegistryPreview/app.ico" />
|
||||
<TextBlock
|
||||
x:Name="titleBarText"
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding ApplicationTitle}" />
|
||||
</Grid>
|
||||
|
||||
<Grid
|
||||
x:Name="gridPreview"
|
||||
Grid.Row="1"
|
||||
Width="Auto"
|
||||
Height="Auto"
|
||||
Margin="12"
|
||||
x:FieldModifier="public"
|
||||
Loaded="GridPreview_Loaded"
|
||||
TabFocusNavigation="Cycle">
|
||||
<Grid.Resources>
|
||||
<Style x:Key="GridCardStyle" TargetType="Border">
|
||||
<Style.Setters>
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource OverlayCornerRadius}" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- Left, Splitter, Right -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="8" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<!-- CommandBar, Tree, Splitter, List -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="8" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="0,0,0,12"
|
||||
Style="{StaticResource GridCardStyle}">
|
||||
|
||||
<CommandBar
|
||||
Name="commandBar"
|
||||
HorizontalAlignment="Left"
|
||||
DefaultLabelPosition="Right">
|
||||
|
||||
<AppBarButton
|
||||
x:Name="openButton"
|
||||
x:Uid="OpenButton"
|
||||
Click="OpenButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="O" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="refreshButton"
|
||||
x:Uid="RefreshButton"
|
||||
Click="RefreshButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="F5" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarSeparator />
|
||||
<AppBarButton
|
||||
x:Name="saveButton"
|
||||
x:Uid="SaveButton"
|
||||
Click="SaveButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="False">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="S" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="saveAsButton"
|
||||
x:Uid="SaveAsButton"
|
||||
Click="SaveAsButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="True">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="S" Modifiers="Control,Shift" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarSeparator />
|
||||
<AppBarButton
|
||||
x:Name="editButton"
|
||||
x:Uid="EditButton"
|
||||
Click="EditButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="E" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="writeButton"
|
||||
x:Uid="WriteButton"
|
||||
Click="WriteButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="W" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="registryButton"
|
||||
x:Uid="RegistryButton"
|
||||
Click="RegistryButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="R" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="registryJumpToKeyButton"
|
||||
x:Uid="RegistryJumpToKeyButton"
|
||||
Click="RegistryJumpToKeyButton_Click"
|
||||
IsEnabled="True">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="R" Modifiers="Control,Shift" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
</CommandBar>
|
||||
</Border>
|
||||
|
||||
<TextBox
|
||||
x:Name="textBox"
|
||||
x:Uid="textBox"
|
||||
Grid.Row="1"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
AcceptsReturn="True"
|
||||
CanBeScrollAnchor="False"
|
||||
CornerRadius="{StaticResource OverlayCornerRadius}"
|
||||
FontFamily="Cascadia Mono, Consolas, Courier New"
|
||||
IsSpellCheckEnabled="False"
|
||||
IsTabStop="True"
|
||||
IsTextPredictionEnabled="False"
|
||||
PlaceholderText="{Binding PlaceholderText}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Visible"
|
||||
ScrollViewer.IsHorizontalRailEnabled="True"
|
||||
ScrollViewer.IsVerticalRailEnabled="True"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||
TabIndex="0"
|
||||
TextWrapping="NoWrap" />
|
||||
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource GridCardStyle}">
|
||||
<TreeView
|
||||
x:Name="treeView"
|
||||
AllowDrop="False"
|
||||
AllowFocusOnInteraction="True"
|
||||
CanDragItems="False"
|
||||
CanReorderItems="False"
|
||||
IsEnabled="True"
|
||||
IsTabStop="False"
|
||||
ItemInvoked="TreeView_ItemInvoked"
|
||||
ScrollViewer.BringIntoViewOnFocusChange="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Visible"
|
||||
ScrollViewer.HorizontalScrollMode="Enabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||
ScrollViewer.VerticalScrollMode="Auto"
|
||||
TabIndex="1">
|
||||
<TreeView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Image
|
||||
MaxWidth="16"
|
||||
MaxHeight="16"
|
||||
Source="{Binding Path=Content.Image}"
|
||||
ToolTipService.ToolTip="{Binding Path=Content.ToolTipText}" />
|
||||
<TextBlock Text="{Binding Path=Content.Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Border>
|
||||
|
||||
<Border
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource GridCardStyle}">
|
||||
<tk7controls:DataGrid
|
||||
x:Name="dataGrid"
|
||||
AllowDrop="False"
|
||||
AreRowDetailsFrozen="True"
|
||||
AutoGenerateColumns="False"
|
||||
CanDrag="False"
|
||||
HeadersVisibility="Column"
|
||||
IsReadOnly="True"
|
||||
IsTabStop="true"
|
||||
ItemsSource="{x:Bind listRegistryValues}"
|
||||
RowDetailsVisibilityMode="Collapsed"
|
||||
SelectionMode="Single"
|
||||
TabIndex="2">
|
||||
<tk7controls:DataGrid.Columns>
|
||||
<tk7controls:DataGridTemplateColumn
|
||||
x:Uid="NameColumn"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<tk7controls:DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel
|
||||
Margin="4"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Image
|
||||
MaxWidth="16"
|
||||
MaxHeight="16"
|
||||
IsTabStop="False"
|
||||
Source="{Binding ImageUri}"
|
||||
ToolTipService.ToolTip="{Binding ToolTipText}" />
|
||||
<TextBlock
|
||||
IsTabStop="False"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</tk7controls:DataGridTemplateColumn.CellTemplate>
|
||||
</tk7controls:DataGridTemplateColumn>
|
||||
<tk7controls:DataGridTextColumn
|
||||
x:Uid="TypeColumn"
|
||||
Width="Auto"
|
||||
Binding="{Binding Type}"
|
||||
FontSize="{StaticResource CaptionTextBlockFontSize}" />
|
||||
<tk7controls:DataGridTextColumn
|
||||
x:Uid="ValueColumn"
|
||||
Width="Auto"
|
||||
Binding="{Binding Value}"
|
||||
FontSize="{StaticResource CaptionTextBlockFontSize}" />
|
||||
</tk7controls:DataGrid.Columns>
|
||||
</tk7controls:DataGrid>
|
||||
</Border>
|
||||
|
||||
<tkcontrols:GridSplitter
|
||||
x:Name="verticalSplitter"
|
||||
Grid.Row="1"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
<tkcontrols:GridSplitter
|
||||
x:Name="horizontalSplitter"
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</winuiex:WindowEx>
|
||||
|
After Width: | Height: | Size: 135 KiB |
|
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 367 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 678 B |
|
Before Width: | Height: | Size: 832 B After Width: | Height: | Size: 832 B |
|
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 356 B |
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Class representing an each item in the tree view, each one a Registry Key;
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Event handler to grab the main window's size and position before it closes
|
||||
/// </summary>
|
||||
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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Event that is will prevent the app from closing if the "save file" flag is active
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
/// <summary>
|
||||
/// Method that opens and processes the passed in file name; expected to be an absolute path and a first time open
|
||||
/// </summary>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the REG file that's being currently being viewed to the app's title bar
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// No REG file was opened, so leave the app's title bar alone
|
||||
/// </summary>
|
||||
private void UpdateWindowTitle()
|
||||
{
|
||||
titleBarText.Text = APPNAME;
|
||||
appWindow.Title = APPNAME;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper method that assumes everything is enabled/disabled together
|
||||
/// </summary>
|
||||
@@ -861,7 +832,7 @@ namespace RegistryPreview
|
||||
}
|
||||
|
||||
// if we got here, we should try to close again
|
||||
App.Current.Exit();
|
||||
Application.Current.Exit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save the window placement JSON blob out to a local file
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Rip the first and last character off a string,
|
||||
/// checking that the string is at least 2 characters long to avoid errors
|
||||
@@ -0,0 +1,270 @@
|
||||
<Page
|
||||
x:Class="RegistryPreviewUILib.RegistryPreviewMainPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:tk7controls="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:tkcontrols="using:CommunityToolkit.WinUI.Controls"
|
||||
xmlns:ui="using:CommunityToolkit.WinUI"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid
|
||||
x:Name="gridPreview"
|
||||
Grid.Row="1"
|
||||
Width="Auto"
|
||||
Height="Auto"
|
||||
Margin="12"
|
||||
x:FieldModifier="public"
|
||||
Loaded="GridPreview_Loaded"
|
||||
TabFocusNavigation="Cycle">
|
||||
<Grid.Resources>
|
||||
<Style x:Key="GridCardStyle" TargetType="Border">
|
||||
<Style.Setters>
|
||||
<Setter Property="Background" Value="{ThemeResource CardBackgroundFillColorDefaultBrush}" />
|
||||
<Setter Property="BorderThickness" Value="1" />
|
||||
<Setter Property="BorderBrush" Value="{ThemeResource CardStrokeColorDefaultBrush}" />
|
||||
<Setter Property="CornerRadius" Value="{StaticResource OverlayCornerRadius}" />
|
||||
</Style.Setters>
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<!-- Left, Splitter, Right -->
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="8" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<!-- CommandBar, Tree, Splitter, List -->
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="8" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Border
|
||||
Grid.Row="0"
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="3"
|
||||
Margin="0,0,0,12"
|
||||
Style="{StaticResource GridCardStyle}">
|
||||
|
||||
<CommandBar
|
||||
Name="commandBar"
|
||||
HorizontalAlignment="Left"
|
||||
DefaultLabelPosition="Right">
|
||||
|
||||
<AppBarButton
|
||||
x:Name="openButton"
|
||||
x:Uid="OpenButton"
|
||||
Click="OpenButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="O" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="refreshButton"
|
||||
x:Uid="RefreshButton"
|
||||
Click="RefreshButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="F5" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarSeparator />
|
||||
<AppBarButton
|
||||
x:Name="saveButton"
|
||||
x:Uid="SaveButton"
|
||||
Click="SaveButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="False">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="S" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="saveAsButton"
|
||||
x:Uid="SaveAsButton"
|
||||
Click="SaveAsButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}"
|
||||
IsEnabled="True">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="S" Modifiers="Control,Shift" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarSeparator />
|
||||
<AppBarButton
|
||||
x:Name="editButton"
|
||||
x:Uid="EditButton"
|
||||
Click="EditButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="E" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="writeButton"
|
||||
x:Uid="WriteButton"
|
||||
Click="WriteButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="W" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="registryButton"
|
||||
x:Uid="RegistryButton"
|
||||
Click="RegistryButton_Click"
|
||||
Icon="{ui:FontIcon Glyph=}">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="R" Modifiers="Control" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="registryJumpToKeyButton"
|
||||
x:Uid="RegistryJumpToKeyButton"
|
||||
Click="RegistryJumpToKeyButton_Click"
|
||||
IsEnabled="True">
|
||||
<AppBarButton.KeyboardAccelerators>
|
||||
<KeyboardAccelerator Key="R" Modifiers="Control,Shift" />
|
||||
</AppBarButton.KeyboardAccelerators>
|
||||
</AppBarButton>
|
||||
</CommandBar>
|
||||
</Border>
|
||||
|
||||
<TextBox
|
||||
x:Name="textBox"
|
||||
x:Uid="textBox"
|
||||
Grid.Row="1"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
AcceptsReturn="True"
|
||||
CanBeScrollAnchor="False"
|
||||
CornerRadius="{StaticResource OverlayCornerRadius}"
|
||||
FontFamily="Cascadia Mono, Consolas, Courier New"
|
||||
IsSpellCheckEnabled="False"
|
||||
IsTabStop="True"
|
||||
IsTextPredictionEnabled="False"
|
||||
PlaceholderText="{Binding PlaceholderText}"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Visible"
|
||||
ScrollViewer.IsHorizontalRailEnabled="True"
|
||||
ScrollViewer.IsVerticalRailEnabled="True"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||
TabIndex="0"
|
||||
TextWrapping="NoWrap" />
|
||||
|
||||
<Border
|
||||
Grid.Row="1"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource GridCardStyle}">
|
||||
<TreeView
|
||||
x:Name="treeView"
|
||||
AllowDrop="False"
|
||||
AllowFocusOnInteraction="True"
|
||||
CanDragItems="False"
|
||||
CanReorderItems="False"
|
||||
IsEnabled="True"
|
||||
IsTabStop="False"
|
||||
ItemInvoked="TreeView_ItemInvoked"
|
||||
ScrollViewer.BringIntoViewOnFocusChange="True"
|
||||
ScrollViewer.HorizontalScrollBarVisibility="Visible"
|
||||
ScrollViewer.HorizontalScrollMode="Enabled"
|
||||
ScrollViewer.VerticalScrollBarVisibility="Visible"
|
||||
ScrollViewer.VerticalScrollMode="Auto"
|
||||
TabIndex="1">
|
||||
<TreeView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Image
|
||||
MaxWidth="16"
|
||||
MaxHeight="16"
|
||||
Source="{Binding Path=Content.Image}"
|
||||
ToolTipService.ToolTip="{Binding Path=Content.ToolTipText}" />
|
||||
<TextBlock Text="{Binding Path=Content.Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</TreeView.ItemTemplate>
|
||||
</TreeView>
|
||||
</Border>
|
||||
|
||||
<Border
|
||||
Grid.Row="3"
|
||||
Grid.Column="2"
|
||||
Style="{StaticResource GridCardStyle}">
|
||||
<tk7controls:DataGrid
|
||||
x:Name="dataGrid"
|
||||
AllowDrop="False"
|
||||
AreRowDetailsFrozen="True"
|
||||
AutoGenerateColumns="False"
|
||||
CanDrag="False"
|
||||
HeadersVisibility="Column"
|
||||
IsReadOnly="True"
|
||||
IsTabStop="true"
|
||||
ItemsSource="{x:Bind listRegistryValues}"
|
||||
RowDetailsVisibilityMode="Collapsed"
|
||||
SelectionMode="Single"
|
||||
TabIndex="2">
|
||||
<tk7controls:DataGrid.Columns>
|
||||
<tk7controls:DataGridTemplateColumn
|
||||
x:Uid="NameColumn"
|
||||
Width="Auto"
|
||||
IsReadOnly="True">
|
||||
<tk7controls:DataGridTemplateColumn.CellTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel
|
||||
Margin="4"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<Image
|
||||
MaxWidth="16"
|
||||
MaxHeight="16"
|
||||
IsTabStop="False"
|
||||
Source="{Binding ImageUri}"
|
||||
ToolTipService.ToolTip="{Binding ToolTipText}" />
|
||||
<TextBlock
|
||||
IsTabStop="False"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding Name}" />
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</tk7controls:DataGridTemplateColumn.CellTemplate>
|
||||
</tk7controls:DataGridTemplateColumn>
|
||||
<tk7controls:DataGridTextColumn
|
||||
x:Uid="TypeColumn"
|
||||
Width="Auto"
|
||||
Binding="{Binding Type}"
|
||||
FontSize="{StaticResource CaptionTextBlockFontSize}" />
|
||||
<tk7controls:DataGridTextColumn
|
||||
x:Uid="ValueColumn"
|
||||
Width="Auto"
|
||||
Binding="{Binding Value}"
|
||||
FontSize="{StaticResource CaptionTextBlockFontSize}" />
|
||||
</tk7controls:DataGrid.Columns>
|
||||
</tk7controls:DataGrid>
|
||||
</Border>
|
||||
|
||||
<tkcontrols:GridSplitter
|
||||
x:Name="verticalSplitter"
|
||||
Grid.Row="1"
|
||||
Grid.RowSpan="3"
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Stretch"
|
||||
IsTabStop="False" />
|
||||
<tkcontrols:GridSplitter
|
||||
x:Name="horizontalSplitter"
|
||||
Grid.Row="2"
|
||||
Grid.Column="2"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Center"
|
||||
IsTabStop="False" />
|
||||
</Grid>
|
||||
</Page>
|
||||
@@ -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<string, TreeViewNode> mapRegistryKeys;
|
||||
private List<RegistryValue> 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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Import Condition="exists('..\..\..\Version.props')" Project="..\..\..\Version.props" />
|
||||
<PropertyGroup>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFramework>net8.0-windows10.0.20348</TargetFramework>
|
||||
<RootNamespace>RegistryPreviewUILib</RootNamespace>
|
||||
<UseWinUI>true</UseWinUI>
|
||||
<EnablePreviewMsixTooling>true</EnablePreviewMsixTooling>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
<AssemblyName>PowerToys.RegistryPreviewUILib</AssemblyName>
|
||||
<!-- MRT from windows app sdk will search for a pri file with the same name of the module before defaulting to resources.pri -->
|
||||
<ProjectPriFileName>PowerToys.RegistryPreviewUILib.pri</ProjectPriFileName>
|
||||
|
||||
<GenerateLibraryLayout>true</GenerateLibraryLayout>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="$(OutDir)\PowerToys.RegistryPreviewUILib.pri" Pack="True" PackageCopyToOutput="true" PackagePath="lib/$(TargetFramework)" />
|
||||
<None Include="$(OutDir)\PowerToys.RegistryPreviewUILib.pri" Pack="True" PackageCopyToOutput="True" PackagePath="contentFiles\any\$(TargetFramework)" />
|
||||
<XBFFile Include="$(OutDir)**\*.xbf" />
|
||||
<None Include="@(XBFFile)" Pack="True" PackageCopyToOutput="True" PackagePath="contentFiles\any\$(TargetFramework)" />
|
||||
<None Include="$(OutDir)\PowerToys.RegistryPreviewUILib.pdb" Pack="True" PackageCopyToOutput="true" PackagePath="lib/$(TargetFramework)" />
|
||||
|
||||
<None Include="Assets\**\*.png" Pack="true" PackageCopyToOutput="true" PackagePath="contentFiles\any\$(TargetFramework)\Assets" />
|
||||
<None Include="Assets\**\*.ico" Pack="true" PackageCopyToOutput="true" PackagePath="contentFiles\any\$(TargetFramework)\Assets" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
<ItemGroup>
|
||||
<Content Remove="Assets\**\*.png" Pack="false" />
|
||||
<Content Remove="Assets\**\*.ico" Pack="false" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<DebugType>full</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Optimize>false</Optimize>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<Optimize>true</Optimize>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Windows.CsWinRT" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls.DataGrid" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Sizers" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Extensions" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||
<PackageReference Include="WinUIEx" />
|
||||
<Manifest Include="$(ApplicationManifest)" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Assets\RegistryPreview\*">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
using System;
|
||||
|
||||
namespace RegistryPreview
|
||||
namespace RegistryPreviewUILib
|
||||
{
|
||||
/// <summary>
|
||||
/// Class representing an each item in the list view, each one a Registry Value.
|
||||
@@ -3,7 +3,7 @@
|
||||
// See the LICENSE file in the project root for more information.
|
||||
using Microsoft.Windows.ApplicationModel.Resources;
|
||||
|
||||
namespace RegistryPreview
|
||||
namespace RegistryPreviewUILib
|
||||
{
|
||||
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.RegistryPreviewUILib.pri", "PowerToys.RegistryPreviewUILib/Resources");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||