mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-16 11:48:06 +01:00
[Registry Preview] Moving to a different API to call the File Picker (#25260)
* Moving from FileOpenPicker Moving from FileOpenPicker to a Win32/PInvoke version, so it can be opened while running as Admin. * Update Resources.resw Replacing a lost string. * Save file picker also crashed Switched to Win32-based SafeFilePicker Cleaned up some of the code which should now pass spell checking and removed pragmas
This commit is contained in:
39
src/modules/registrypreview/RegistryPreviewUI/FileName.cs
Normal file
39
src/modules/registrypreview/RegistryPreviewUI/FileName.cs
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
/// <summary>
|
||||
/// Uses a picker to save out a copy of the current reg file
|
||||
/// </summary>
|
||||
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<string>() { ".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));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@
|
||||
<AssemblyDescription>PowerToys RegistryPreview</AssemblyDescription>
|
||||
<RootNamespace>RegistryPreview</RootNamespace>
|
||||
<DisableWinExeOutputInference>true</DisableWinExeOutputInference>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- SelfContained=true requires RuntimeIdentifier to be set -->
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,12 @@
|
||||
<data name="FileSaveError" xml:space="preserve">
|
||||
<value>The REG file cannot be written to.</value>
|
||||
</data>
|
||||
<data name="FilterAllFiles" xml:space="preserve">
|
||||
<value>All files (*.*)</value>
|
||||
</data>
|
||||
<data name="FilterRegistryName" xml:space="preserve">
|
||||
<value>Registry files (*.reg)</value>
|
||||
</data>
|
||||
<data name="InvalidRegistryFile" xml:space="preserve">
|
||||
<value> doesn't appear to be a valid registry file!</value>
|
||||
</data>
|
||||
@@ -153,8 +159,8 @@
|
||||
<data name="OpenButton.Label" xml:space="preserve">
|
||||
<value>Open file...</value>
|
||||
</data>
|
||||
<data name="OpenButtonText" xml:space="preserve">
|
||||
<value>Open</value>
|
||||
<data name="OpenDialogTitle" xml:space="preserve">
|
||||
<value>Open Registry file...</value>
|
||||
</data>
|
||||
<data name="RefreshButton.Label" xml:space="preserve">
|
||||
<value>Reload from file</value>
|
||||
|
||||
Reference in New Issue
Block a user