diff --git a/src/modules/registrypreview/RegistryPreviewUI/FileName.cs b/src/modules/registrypreview/RegistryPreviewUI/FileName.cs
new file mode 100644
index 0000000000..7464fff039
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUI/FileName.cs
@@ -0,0 +1,39 @@
+// 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 RegistryPreview
+{
+ // Workaround for File Pickers that don't work while running as admin, per:
+ // https://github.com/microsoft/WindowsAppSDK/issues/2504
+ [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
+ public struct FileName
+ {
+ public int StructSize;
+ public IntPtr HwndOwner;
+ public IntPtr Instance;
+ public string Filter;
+ public string CustomFilter;
+ public int MaxCustFilter;
+ public int FilterIndex;
+ public string File;
+ public int MaxFile;
+ public string FileTitle;
+ public int MaxFileTitle;
+ public string InitialDir;
+ public string Title;
+ public int Flags;
+ public short FileOffset;
+ public short FileExtension;
+ public string DefExt;
+ public IntPtr CustData;
+ public IntPtr Hook;
+ public string TemplateName;
+ public IntPtr PtrReserved;
+ public int Reserved;
+ public int FlagsEx;
+ }
+}
diff --git a/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs b/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs
index 949bb3b7b0..90eb9f2c24 100644
--- a/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs
+++ b/src/modules/registrypreview/RegistryPreviewUI/MainWindow.Events.cs
@@ -134,18 +134,18 @@ namespace RegistryPreview
}
}
- // Pull in a new REG file
- FileOpenPicker fileOpenPicker = new FileOpenPicker();
- fileOpenPicker.ViewMode = PickerViewMode.List;
- fileOpenPicker.CommitButtonText = resourceLoader.GetString("OpenButtonText");
- fileOpenPicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
- fileOpenPicker.FileTypeFilter.Add(".reg");
+ // 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
+ string filename = OpenFilePicker.ShowDialog(
+ resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
+ resourceLoader.GetString("OpenDialogTitle"));
- // Get the HWND so we an open the modal
- IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
- InitializeWithWindow.Initialize(fileOpenPicker, hWnd);
+ if (filename == string.Empty || File.Exists(filename) == false)
+ {
+ return;
+ }
- StorageFile storageFile = await fileOpenPicker.PickSingleFileAsync();
+ StorageFile storageFile = await StorageFile.GetFileFromPathAsync(filename);
if (storageFile != null)
{
@@ -174,27 +174,23 @@ namespace RegistryPreview
///
/// Uses a picker to save out a copy of the current reg file
///
- private async void SaveAsButton_Click(object sender, RoutedEventArgs e)
+ private void SaveAsButton_Click(object sender, RoutedEventArgs e)
{
- // Save out a new REG file and then open it
- FileSavePicker fileSavePicker = new FileSavePicker();
- fileSavePicker.CommitButtonText = resourceLoader.GetString("SaveButtonText");
- fileSavePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary;
- fileSavePicker.FileTypeChoices.Add("Registry file", new List() { ".reg" });
- fileSavePicker.SuggestedFileName = resourceLoader.GetString("SuggestFileName");
+ // 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
+ string filename = SaveFilePicker.ShowDialog(
+ resourceLoader.GetString("SuggestFileName"),
+ resourceLoader.GetString("FilterRegistryName") + '\0' + "*.reg" + '\0' + resourceLoader.GetString("FilterAllFiles") + '\0' + "*.*" + '\0' + '\0',
+ resourceLoader.GetString("SaveDialogTitle"));
- // Get the HWND so we an save the modal
- IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(this);
- InitializeWithWindow.Initialize(fileSavePicker, hWnd);
-
- StorageFile storageFile = await fileSavePicker.PickSaveFileAsync();
-
- if (storageFile != null)
+ if (filename == string.Empty)
{
- App.AppFilename = storageFile.Path;
- SaveFile();
- UpdateToolBarAndUI(OpenRegistryFile(App.AppFilename));
+ return;
}
+
+ App.AppFilename = filename;
+ SaveFile();
+ UpdateToolBarAndUI(OpenRegistryFile(App.AppFilename));
}
///
diff --git a/src/modules/registrypreview/RegistryPreviewUI/OpenFileName.cs b/src/modules/registrypreview/RegistryPreviewUI/OpenFileName.cs
new file mode 100644
index 0000000000..c6dc243aeb
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUI/OpenFileName.cs
@@ -0,0 +1,36 @@
+// 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.Runtime.InteropServices;
+
+namespace RegistryPreview
+{
+ // Workaround for File Pickers that don't work while running as admin, per:
+ // https://github.com/microsoft/WindowsAppSDK/issues/2504
+ public static partial class OpenFilePicker
+ {
+ [DllImport("comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern bool GetOpenFileName(ref FileName openFileName);
+
+ public static string ShowDialog(string filter, string dialogTitle)
+ {
+ FileName openFileName = default(FileName);
+ openFileName.StructSize = Marshal.SizeOf(openFileName);
+
+ openFileName.Filter = filter;
+ openFileName.File = new string(new char[256]);
+ openFileName.MaxFile = openFileName.File.Length;
+ openFileName.FileTitle = new string(new char[64]);
+ openFileName.MaxFileTitle = openFileName.FileTitle.Length;
+ openFileName.Title = dialogTitle;
+
+ if (GetOpenFileName(ref openFileName))
+ {
+ return openFileName.File;
+ }
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj b/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj
index 4abd57ccda..9e68b9e7b4 100644
--- a/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj
+++ b/src/modules/registrypreview/RegistryPreviewUI/RegistryPreviewUI.csproj
@@ -24,6 +24,7 @@
PowerToys RegistryPreview
RegistryPreview
true
+ true
diff --git a/src/modules/registrypreview/RegistryPreviewUI/SaveFileName.cs b/src/modules/registrypreview/RegistryPreviewUI/SaveFileName.cs
new file mode 100644
index 0000000000..0e0f2d58a7
--- /dev/null
+++ b/src/modules/registrypreview/RegistryPreviewUI/SaveFileName.cs
@@ -0,0 +1,38 @@
+// 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.Runtime.InteropServices;
+
+namespace RegistryPreview
+{
+ // Workaround for File Pickers that don't work while running as admin, per:
+ // https://github.com/microsoft/WindowsAppSDK/issues/2504
+ public static partial class SaveFilePicker
+ {
+ [DllImport("comdlg32.dll", SetLastError = true, CharSet = CharSet.Auto)]
+ private static extern bool GetSaveFileName(ref FileName saveFileName);
+
+ public static string ShowDialog(string suggestedFilename, string filter, string dialogTitle)
+ {
+ FileName saveFileName = default(FileName);
+ saveFileName.StructSize = Marshal.SizeOf(saveFileName);
+
+ saveFileName.Filter = filter;
+ saveFileName.File = new string(new char[256]);
+ saveFileName.MaxFile = saveFileName.File.Length;
+ saveFileName.File = string.Concat(suggestedFilename, saveFileName.File);
+ saveFileName.FileTitle = new string(new char[64]);
+ saveFileName.MaxFileTitle = saveFileName.FileTitle.Length;
+ saveFileName.Title = dialogTitle;
+ saveFileName.DefExt = "reg";
+
+ if (GetSaveFileName(ref saveFileName))
+ {
+ return saveFileName.File;
+ }
+
+ return string.Empty;
+ }
+ }
+}
diff --git a/src/modules/registrypreview/RegistryPreviewUI/Strings/en-US/Resources.resw b/src/modules/registrypreview/RegistryPreviewUI/Strings/en-US/Resources.resw
index 6108bf8eec..d64bc8f063 100644
--- a/src/modules/registrypreview/RegistryPreviewUI/Strings/en-US/Resources.resw
+++ b/src/modules/registrypreview/RegistryPreviewUI/Strings/en-US/Resources.resw
@@ -132,6 +132,12 @@
The REG file cannot be written to.
+
+ All files (*.*)
+
+
+ Registry files (*.reg)
+
doesn't appear to be a valid registry file!
@@ -153,8 +159,8 @@
Open file...
-
- Open
+
+ Open Registry file...
Reload from file