mirror of
https://github.com/rbalsleyMSFT/FFU.git
synced 2026-06-14 02:09:35 -06:00
Adds support for an initial directory in folder picker
Enhances the modern folder browser to accept and open to a specified initial directory. This improves the user experience by starting the "Browse for Drivers" dialog in the project's 'Drivers' subfolder, reducing the need for manual navigation. The implementation uses the Win32 API to create a shell item from the initial path and set it as the dialog's starting folder.
This commit is contained in:
@@ -594,7 +594,8 @@ function Register-EventHandlers {
|
|||||||
param($eventSource, $routedEventArgs)
|
param($eventSource, $routedEventArgs)
|
||||||
$window = [System.Windows.Window]::GetWindow($eventSource)
|
$window = [System.Windows.Window]::GetWindow($eventSource)
|
||||||
$localState = $window.Tag
|
$localState = $window.Tag
|
||||||
$selectedPath = Invoke-BrowseAction -Type 'Folder' -Title "Select Drivers Folder"
|
$initialDir = Join-Path -Path $localState.FFUDevelopmentPath -ChildPath "Drivers"
|
||||||
|
$selectedPath = Invoke-BrowseAction -Type 'Folder' -Title "Select Drivers Folder" -InitialDirectory $initialDir
|
||||||
if ($selectedPath) {
|
if ($selectedPath) {
|
||||||
$localState.Controls.txtDriversFolder.Text = $selectedPath
|
$localState.Controls.txtDriversFolder.Text = $selectedPath
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -620,15 +620,17 @@ function Invoke-ListViewSort {
|
|||||||
|
|
||||||
# 1) Define a C# class that uses the correct GUIDs for IFileDialog, IFileOpenDialog, and FileOpenDialog,
|
# 1) Define a C# class that uses the correct GUIDs for IFileDialog, IFileOpenDialog, and FileOpenDialog,
|
||||||
# while omitting conflicting "GetResults/GetSelectedItems" from IFileDialog.
|
# while omitting conflicting "GetResults/GetSelectedItems" from IFileDialog.
|
||||||
Add-Type -TypeDefinition @"
|
if (-not ("ModernFolderBrowser" -as [type])) {
|
||||||
using System;
|
$modernFolderBrowserCode = @"
|
||||||
using System.Runtime.InteropServices;
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
public static class ModernFolderBrowser
|
public static class ModernFolderBrowser
|
||||||
{
|
{
|
||||||
// Flags for IFileDialog
|
// Flags for IFileDialog
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum FileDialogOptions : uint
|
private enum FileDialogOptions : uint
|
||||||
|
|
||||||
{
|
{
|
||||||
OverwritePrompt = 0x00000002,
|
OverwritePrompt = 0x00000002,
|
||||||
StrictFileTypes = 0x00000004,
|
StrictFileTypes = 0x00000004,
|
||||||
@@ -718,9 +720,13 @@ public static class ModernFolderBrowser
|
|||||||
void Compare(IShellItem psi, uint hint, out int piOrder);
|
void Compare(IShellItem psi, uint hint, out int piOrder);
|
||||||
}
|
}
|
||||||
|
|
||||||
private const uint SIGDN_FILESYSPATH = 0x80058000;
|
[DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||||
|
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, [MarshalAs(UnmanagedType.Interface, IidParameterIndex = 2)] out IShellItem ppv);
|
||||||
|
|
||||||
public static string ShowDialog(string title, IntPtr parentHandle)
|
private const uint SIGDN_FILESYSPATH = 0x80058000;
|
||||||
|
private static readonly Guid IID_IShellItem = new Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE");
|
||||||
|
|
||||||
|
public static string ShowDialog(string title, IntPtr parentHandle, string initialDirectory)
|
||||||
{
|
{
|
||||||
// Create COM dialog instance
|
// Create COM dialog instance
|
||||||
IFileOpenDialog dialog = (IFileOpenDialog)(new FileOpenDialog());
|
IFileOpenDialog dialog = (IFileOpenDialog)(new FileOpenDialog());
|
||||||
@@ -733,6 +739,24 @@ public static class ModernFolderBrowser
|
|||||||
opts |= FileDialogOptions.PickFolders | FileDialogOptions.PathMustExist | FileDialogOptions.ForceFileSystem;
|
opts |= FileDialogOptions.PickFolders | FileDialogOptions.PathMustExist | FileDialogOptions.ForceFileSystem;
|
||||||
dialog.SetOptions(opts);
|
dialog.SetOptions(opts);
|
||||||
|
|
||||||
|
// Set initial directory if provided
|
||||||
|
if (!string.IsNullOrEmpty(initialDirectory))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Guid iid = IID_IShellItem; // Create a local copy to pass by ref
|
||||||
|
if (SHCreateItemFromParsingName(initialDirectory, IntPtr.Zero, ref iid, out IShellItem initialFolder) == 0)
|
||||||
|
{
|
||||||
|
dialog.SetFolder(initialFolder);
|
||||||
|
Marshal.ReleaseComObject(initialFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignore errors in setting initial directory (e.g., path doesn't exist)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set title
|
// Set title
|
||||||
if (!string.IsNullOrEmpty(title))
|
if (!string.IsNullOrEmpty(title))
|
||||||
{
|
{
|
||||||
@@ -769,16 +793,19 @@ public static class ModernFolderBrowser
|
|||||||
|
|
||||||
return folderPath;
|
return folderPath;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
Add-Type -TypeDefinition $modernFolderBrowserCode -Language CSharp
|
||||||
}
|
}
|
||||||
"@ -Language CSharp
|
|
||||||
|
|
||||||
# 2) Define a PowerShell function that invokes our C# wrapper
|
# 2) Define a PowerShell function that invokes our C# wrapper
|
||||||
function Show-ModernFolderPicker {
|
function Show-ModernFolderPicker {
|
||||||
param(
|
param(
|
||||||
[string]$Title = "Select a folder"
|
[string]$Title = "Select a folder",
|
||||||
|
[string]$InitialDirectory
|
||||||
)
|
)
|
||||||
# For a simple test, pass IntPtr.Zero as the parent window handle
|
# For a simple test, pass IntPtr.Zero as the parent window handle
|
||||||
return [ModernFolderBrowser]::ShowDialog($Title, [IntPtr]::Zero)
|
return [ModernFolderBrowser]::ShowDialog($Title, [IntPtr]::Zero, $InitialDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
function Invoke-BrowseAction {
|
function Invoke-BrowseAction {
|
||||||
@@ -797,8 +824,7 @@ function Invoke-BrowseAction {
|
|||||||
|
|
||||||
switch ($Type) {
|
switch ($Type) {
|
||||||
'Folder' {
|
'Folder' {
|
||||||
# Show-ModernFolderPicker does not currently support setting an initial directory.
|
return Show-ModernFolderPicker -Title $Title -InitialDirectory $InitialDirectory
|
||||||
return Show-ModernFolderPicker -Title $Title
|
|
||||||
}
|
}
|
||||||
'OpenFile' {
|
'OpenFile' {
|
||||||
$dialog = New-Object Microsoft.Win32.OpenFileDialog
|
$dialog = New-Object Microsoft.Win32.OpenFileDialog
|
||||||
|
|||||||
Reference in New Issue
Block a user