Skip to content

Instantly share code, notes, and snippets.

@joshooaj
Created August 4, 2023 20:13
Show Gist options
  • Select an option

  • Save joshooaj/63d1a88ea5bec2189442dd26c88de5b5 to your computer and use it in GitHub Desktop.

Select an option

Save joshooaj/63d1a88ea5bec2189442dd26c88de5b5 to your computer and use it in GitHub Desktop.
Show the Windows open, save, and folder browser dialogs
Add-Type -AssemblyName System.Windows.Forms
Add-Type @'
using System;
using System.Runtime.InteropServices;
public class WindowHelper {
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
'@
function Show-OpenFileDialog {
<#
.SYNOPSIS
Shows the Windows OpenFileDialog and returns the user-selected file path(s).
.DESCRIPTION
For detailed information on the available parameters, see the OpenFileDialog
class documentation online at https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.openfiledialog?view=netframework-4.8.1
#>
[CmdletBinding()]
[OutputType([string])]
param (
[Parameter()]
[bool]
$AddExtension = $true,
[Parameter()]
[bool]
$AutoUpgradeEnabled = $true,
[Parameter()]
[bool]
$CheckFileExists = $true,
[Parameter()]
[bool]
$CheckPathExists = $true,
[Parameter()]
[string]
$DefaultExt,
[Parameter()]
[bool]
$DereferenceLinks = $true,
# Filter for specific file types. Example syntax: 'Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*'
[Parameter()]
[string]
$Filter,
[Parameter()]
[string]
$InitialDirectory,
[Parameter()]
[bool]
$Multiselect,
[Parameter()]
[bool]
$ReadOnlyChecked,
[Parameter()]
[bool]
$RestoreDirectory,
[Parameter()]
[bool]
$ShowHelp,
[Parameter()]
[bool]
$ShowReadOnly,
[Parameter()]
[bool]
$SupportMultiDottedExtensions,
[Parameter()]
[string]
$Title,
[Parameter()]
[bool]
$ValidateNames
)
process {
$params = @{
AddExtension = $AddExtension
AutoUpgradeEnabled = $AutoUpgradeEnabled
CheckFileExists = $CheckFileExists
CheckPathExists = $CheckPathExists
DefaultExt = $DefaultExt
DereferenceLinks = $DereferenceLinks
Filter = $Filter
InitialDirectory = $InitialDirectory
Multiselect = $Multiselect
ReadOnlyChecked = $ReadOnlyChecked
RestoreDirectory = $RestoreDirectory
ShowHelp = $ShowHelp
ShowReadOnly = $ShowReadOnly
SupportMultiDottedExtensions = $SupportMultiDottedExtensions
Title = $Title
ValidateNames = $ValidateNames
}
[System.Windows.Forms.Form]$form = $null
[System.Windows.Forms.OpenFileDialog]$dialog = $null
try {
$form = [System.Windows.Forms.Form]@{ TopMost = $true }
$dialog = [System.Windows.Forms.OpenFileDialog]$params
$CustomPlaces | ForEach-Object {
if ($null -eq $_) {
return
}
if (($id = $_ -as [guid])) {
$dialog.CustomPlaces.Add($id)
} else {
$dialog.CustomPlaces.Add($_)
}
}
$null = [WindowHelper]::SetForegroundWindow($form.Handle)
if ($dialog.ShowDialog($form) -eq 'OK') {
if ($MultiSelect) {
$dialog.FileNames
} else {
$dialog.FileName
}
} else {
Write-Error -Message 'No file(s) selected.'
}
} finally {
if ($dialog) {
$dialog.Dispose()
}
if ($form) {
$form.Dispose()
}
}
}
}
function Show-SaveFileDialog {
<#
.SYNOPSIS
Shows the Windows SaveFileDialog and returns the user-provided file path.
.DESCRIPTION
For detailed information on the available parameters, see the SaveFileDialog
class documentation online at https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.savefiledialog?view=netframework-4.8.1
#>
[CmdletBinding()]
[OutputType([string])]
param (
[Parameter()]
[bool]
$AddExtension = $true,
[Parameter()]
[bool]
$AutoUpgradeEnabled = $true,
[Parameter()]
[bool]
$CheckFileExists = $false,
[Parameter()]
[bool]
$CheckPathExists = $true,
[Parameter()]
[bool]
$CreatePrompt,
[Parameter()]
[string[]]
$CustomPlaces,
[Parameter()]
[string]
$DefaultExt,
[Parameter()]
[bool]
$DereferenceLinks = $true,
# Filter for specific file types. Example syntax: 'Excel files (*.xlsx)|*.xlsx|All files (*.*)|*.*'
[Parameter()]
[string]
$Filter,
[Parameter()]
[string]
$InitialDirectory,
[Parameter()]
[bool]
$OverwritePrompt = $true,
[Parameter()]
[bool]
$RestoreDirectory,
[Parameter()]
[bool]
$ShowHelp,
[Parameter()]
[bool]
$SupportMultiDottedExtensions,
[Parameter()]
[string]
$Title,
[Parameter()]
[bool]
$ValidateNames = $true
)
process {
$params = @{
AddExtension = $AddExtension
AutoUpgradeEnabled = $AutoUpgradeEnabled
CheckFileExists = $CheckFileExists
CheckPathExists = $CheckPathExists
CreatePrompt = $CreatePrompt
DefaultExt = $DefaultExt
DereferenceLinks = $DereferenceLinks
Filter = $Filter
InitialDirectory = $InitialDirectory
OverwritePrompt = $OverwritePrompt
RestoreDirectory = $RestoreDirectory
ShowHelp = $ShowHelp
SupportMultiDottedExtensions = $SupportMultiDottedExtensions
Title = $Title
ValidateNames = $ValidateNames
}
[System.Windows.Forms.Form]$form = $null
[System.Windows.Forms.SaveFileDialog]$dialog = $null
try {
$form = [System.Windows.Forms.Form]@{ TopMost = $true }
$dialog = [System.Windows.Forms.SaveFileDialog]$params
$CustomPlaces | ForEach-Object {
if ($null -eq $_) {
return
}
if (($id = $_ -as [guid])) {
$dialog.CustomPlaces.Add($id)
} else {
$dialog.CustomPlaces.Add($_)
}
}
$null = [WindowHelper]::SetForegroundWindow($form.Handle)
if (($dialogResult = $dialog.ShowDialog($form)) -eq 'OK') {
$dialog.FileName
} else {
Write-Error -Message "DialogResult: $dialogResult"
}
} finally {
if ($dialog) {
$dialog.Dispose()
}
if ($form) {
$form.Dispose()
}
}
}
}
function Show-FolderBrowserDialog {
<#
.SYNOPSIS
Shows the Windows FolderBrowserDialog and returns the user-selected path.
.DESCRIPTION
For detailed information on the available parameters, see the FolderBrowserDialog
class documentation online at https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.folderbrowserdialog?view=netframework-4.8.1
#>
[CmdletBinding()]
[OutputType([string])]
param (
[Parameter()]
[string]
$Description,
[Parameter()]
[System.Environment+SpecialFolder]
$RootFolder,
[Parameter()]
[bool]
$ShowNewFolderButton = $true
)
process {
$params = @{
Description = $Description
ShowNewFolderButton = $ShowNewFolderButton
}
if ($MyInvocation.BoundParameters.ContainsKey('RootFolder')) {
$params.RootFolder = $RootFolder
}
[System.Windows.Forms.Form]$form = $null
[System.Windows.Forms.FolderBrowserDialog]$dialog = $null
try {
$form = [System.Windows.Forms.Form]@{ TopMost = $true }
$form.add_Shown({ $args[0].Activete() })
$dialog = [System.Windows.Forms.FolderBrowserDialog]$params
$null = [WindowHelper]::SetForegroundWindow($form.Handle)
if (($dialogResult = $dialog.ShowDialog($form)) -eq 'OK') {
$dialog.SelectedPath
} else {
Write-Error -Message "DialogResult: $dialogResult"
}
} finally {
if ($dialog) {
$dialog.Dispose()
}
if ($form) {
$form.Dispose()
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment