powershellfolderbrowserdialog

PowerScript: System.Windows.Forms.FolderBrowserDialog opening in the background


PowerScript Noob here.

I've found a snippet of code that lets the user select a folder thru a Folder Browser Dialog, instead of having enter the path to the folder manually.

Works as expected, except the Folder Browser Dialog often opens behind other windows on the screen, which is getting tiresome.

Here is the code:

Function Get-Folder($initialDirectory)

{
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")|Out-Null

    $foldername = New-Object System.Windows.Forms.FolderBrowserDialog
    $foldername.Description = "Select a folder"
    $foldername.rootfolder = "MyComputer"
    $foldername.SelectedPath = $initialDirectory

    if($foldername.ShowDialog() -eq "OK")
    {
        $folder += $foldername.SelectedPath
    }
    return $folder
}

$FolderNavn = Get-Folder($StartFolder)

How do I get the Folder Browser Dialog to open 'on top of' all other Windows?

Thanks.


Solution

  • To set the BrowseForFolder dialog TopMost, you need to use the ShowDialog() overloaded method with a parameter that specifies the dialogs owner (parent) form.

    The easiest I think it to just create a new Form with property Topmost set to $true and use that as owner form:

    function Get-Folder {
        [CmdletBinding()]
        param (
            [Parameter(Mandatory=$false, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)]
            [string]$Message = "Please select a directory.",
    
            [Parameter(Mandatory=$false, Position=1)]
            [string]$InitialDirectory,
    
            [Parameter(Mandatory=$false)]
            [System.Environment+SpecialFolder]$RootFolder = [System.Environment+SpecialFolder]::Desktop,
    
            [switch]$ShowNewFolderButton
        )
        Add-Type -AssemblyName System.Windows.Forms
        $dialog = New-Object System.Windows.Forms.FolderBrowserDialog
        $dialog.Description  = $Message
        $dialog.SelectedPath = $InitialDirectory
        $dialog.RootFolder   = $RootFolder
        $dialog.ShowNewFolderButton = if ($ShowNewFolderButton) { $true } else { $false }
        $selected = $null
    
        # force the dialog TopMost
        # Since the owning window will not be used after the dialog has been 
        # closed we can just create a new form on the fly within the method call
        $result = $dialog.ShowDialog((New-Object System.Windows.Forms.Form -Property @{TopMost = $true }))
        if ($result -eq [Windows.Forms.DialogResult]::OK){
            $selected = $dialog.SelectedPath
        }
        # clear the FolderBrowserDialog from memory
        $dialog.Dispose()
        # return the selected folder
        $selected
    }