diff --git a/src/modules/registrypreview/RegistryPreviewUILib/ClipboardHelper.cs b/src/modules/registrypreview/RegistryPreviewUILib/ClipboardHelper.cs
new file mode 100644
index 000000000000..7df10de2fac3
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUILib/ClipboardHelper.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 System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Windows.ApplicationModel.DataTransfer;
+
+namespace RegistryPreviewUILib
+{
+ ///
+ /// Helper class to centralize clipboard actions
+ ///
+ internal static class ClipboardHelper
+ {
+ internal static void CopyToClipboardAction(string text)
+ {
+ try
+ {
+ var data = new DataPackage();
+ data.SetText(text);
+ Clipboard.SetContent(data);
+ Clipboard.Flush();
+ }
+ catch
+ {
+ }
+ }
+ }
+}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs
index 44660000592f..6a190bcdb2b4 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryKey.xaml.cs
@@ -2,6 +2,10 @@
// 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.Windows.Input;
+using CommunityToolkit.Mvvm.Input;
+using Windows.ApplicationModel.DataTransfer;
+
namespace RegistryPreviewUILib
{
///
@@ -28,5 +32,19 @@ public RegistryKey(string name, string fullPath, string image, string toolTipTex
this.Image = image;
this.ToolTipText = toolTipText;
}
+
+ public ICommand CopyToClipboardName_Click => new RelayCommand(CopyToClipboardName);
+
+ public ICommand CopyToClipboardKeyPath_Click => new RelayCommand(CopyToClipboardKeyPath);
+
+ private void CopyToClipboardName()
+ {
+ ClipboardHelper.CopyToClipboardAction(Name);
+ }
+
+ private void CopyToClipboardKeyPath()
+ {
+ ClipboardHelper.CopyToClipboardAction(FullPath);
+ }
}
}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
index b3073669f7b7..b8fc6e4e1d9a 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.Utilities.cs
@@ -23,6 +23,7 @@ namespace RegistryPreviewUILib
public sealed partial class RegistryPreviewMainPage : Page
{
private static SemaphoreSlim _dialogSemaphore = new(1);
+ private string lastKeyPath;
public delegate void UpdateWindowTitleFunction(string title);
@@ -261,6 +262,7 @@ private bool ParseRegistryFile(string filenameText)
registryLine = StripFirstAndLast(registryLine);
treeViewNode = AddTextToTree(registryLine, imageName);
+ lastKeyPath = registryLine;
}
else if (registryLine.StartsWith('"') && registryLine.EndsWith("=-", StringComparison.InvariantCulture))
{
@@ -271,7 +273,7 @@ private bool ParseRegistryFile(string filenameText)
registryLine = StripFirstAndLast(registryLine);
// Create a new listview item that will be used to display the delete value and store it
- registryValue = new RegistryValue(registryLine, string.Empty, string.Empty);
+ registryValue = new RegistryValue(registryLine, string.Empty, string.Empty, lastKeyPath);
SetValueToolTip(registryValue);
// store the ListViewItem, if we have a valid Key to attach to
@@ -310,7 +312,7 @@ private bool ParseRegistryFile(string filenameText)
value = value.Trim();
// Create a new listview item that will be used to display the value
- registryValue = new RegistryValue(name, "REG_SZ", string.Empty);
+ registryValue = new RegistryValue(name, "REG_SZ", string.Empty, lastKeyPath);
// if the first character is a " then this is a string value, so find the last most " which will avoid comments
if (value.StartsWith('"'))
@@ -553,19 +555,10 @@ private bool ParseRegistryFile(string filenameText)
var bytes = value.Split(',').Select(
c => c.Length == 2 ? byte.Parse(c, NumberStyles.HexNumber, CultureInfo.InvariantCulture) : throw null).ToArray();
- if (registryValue.Type == "REG_MULTI_SZ")
- {
- // Replace zeros (00,00) with spaces
- for (int i = 0; i < bytes.Length; i += 2)
- {
- if (bytes[i] == 0 && bytes[i + 1] == 0)
- {
- bytes[i] = 0x20;
- }
- }
- }
-
value = Encoding.Unicode.GetString(bytes);
+
+ // Correctly format line breaks and remove trailing line breaks. (GitHub PowerToys #36629)
+ value = value.Replace('\0', '\r').TrimEnd('\r');
}
catch
{
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml
index 058663459ec4..a48222e9aa8f 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml
@@ -167,6 +167,12 @@
IsTabStop="False"
Orientation="Horizontal"
Spacing="8">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+ IsReadOnly="True">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs
index 1687a24293d3..06e435c9f0e4 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryPreviewMainPage.xaml.cs
@@ -8,6 +8,7 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.Windows.ApplicationModel.Resources;
+using Windows.ApplicationModel.DataTransfer;
namespace RegistryPreviewUILib
{
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs
index 3e0d16c9328f..1bf403c3fab1 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs
+++ b/src/modules/registrypreview/RegistryPreviewUILib/RegistryValue.xaml.cs
@@ -3,6 +3,10 @@
// See the LICENSE file in the project root for more information.
using System;
+using System.Windows.Input;
+using CommunityToolkit.Mvvm.Input;
+using Microsoft.UI.Xaml;
+using Windows.ApplicationModel.DataTransfer;
namespace RegistryPreviewUILib
{
@@ -17,12 +21,16 @@ public class RegistryValue
private static Uri uriDeleteValue = new Uri("ms-appx:///Assets/RegistryPreview/deleted-value32.png");
private static Uri uriErrorValue = new Uri("ms-appx:///Assets/RegistryPreview/error32.png");
+ public string Key { get; set; }
+
public string Name { get; set; }
public string Type { get; set; }
public string Value { get; set; }
+ public string ValueOneLine => Value.Replace('\r', ' ');
+
public string ToolTipText { get; set; }
public Uri ImageUri
@@ -46,12 +54,49 @@ public Uri ImageUri
}
}
- public RegistryValue(string name, string type, string value)
+ public RegistryValue(string name, string type, string value, string key)
{
this.Name = name;
this.Type = type;
this.Value = value;
this.ToolTipText = string.Empty;
+ this.Key = key;
+ }
+
+ // Commands
+ public ICommand CopyToClipboardEntry_Click => new RelayCommand(CopyToClipboardEntry);
+
+ public ICommand CopyToClipboardWithPath_Click => new RelayCommand(CopyToClipboardEntryWithPath);
+
+ public ICommand CopyToClipboardName_Click => new RelayCommand(CopyToClipboardName);
+
+ public ICommand CopyToClipboardType_Click => new RelayCommand(CopyToClipboardType);
+
+ public ICommand CopyToClipboardData_Click => new RelayCommand(CopyToClipboardData);
+
+ private void CopyToClipboardEntry()
+ {
+ ClipboardHelper.CopyToClipboardAction($"{Name}\r\n{Type}\r\n{Value}");
+ }
+
+ private void CopyToClipboardEntryWithPath()
+ {
+ ClipboardHelper.CopyToClipboardAction($"{Key}\r\n{Name}\r\n{Type}\r\n{Value}");
+ }
+
+ private void CopyToClipboardName()
+ {
+ ClipboardHelper.CopyToClipboardAction(Name);
+ }
+
+ private void CopyToClipboardType()
+ {
+ ClipboardHelper.CopyToClipboardAction(Type);
+ }
+
+ private void CopyToClipboardData()
+ {
+ ClipboardHelper.CopyToClipboardAction(Value);
}
}
}
diff --git a/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw
index 580d108d9a7b..9401908d216e 100644
--- a/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw
+++ b/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw
@@ -257,4 +257,28 @@
(zero-length binary value)
+
+ Copy path
+ Like "Copy item"
+
+
+ Copy name
+ Like "Copy item"
+
+
+ Copy type
+ Like "Copy item"
+
+
+ Copy data
+ Like "Copy item"
+
+
+ Copy value
+ Like "Copy item"
+
+
+ Copy value with key path
+ Like "Copy item"
+
\ No newline at end of file