Question

Back in cmd.exe, I used

set /P file=Enter path to the file: 

to enter file path from console (if it wasn't supplied as a parameter), and I could press Tab to get path auto-completion. However, when I execute in Powershell

$file = Read-Host -Prompt "Enter path to the file"

then I cannot use Tab to get auto-completion, it just inserts a tabulation in the input. IS there a way to simulate the former behaviour?

Was it helpful?

Solution

I know, I know... not really an answer to your question directly, but still totally worth mentioning IMHO. Why ask the user to type out a path (and chance typos) when you can just pop up a Open File dialog box? Drop this function at the beginning of the script:

function Get-FileName($initialDirectory)
{   
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") |
    Out-Null

    $OpenFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $OpenFileDialog.initialDirectory = $initialDirectory
    $OpenFileDialog.filter = "All files (*.*)| *.*"
    $OpenFileDialog.ShowDialog() | Out-Null
    $OpenFileDialog.filename
}

Then when you need to get a file name and path you can just do $file = get-filename and be done with it. If you only want certain file types you can change the filter line to only allow the user to see certain kinds of files, or even a specific file name (i.e. you need them to locate 'computerlist.csv' on the hard drive or something, you can change the . in the filter to computerlist.csv).

OTHER TIPS

Based on the idea of JG in SD, the version of the selection folder is given here.

function Get-FolderPath($initialDirectory)
{   
    [System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") > $null
    $FolderBrowserDialog = New-Object System.Windows.Forms.FolderBrowserDialog
    $FolderBrowserDialog.SelectedPath = $initialDirectory
    $FolderBrowserDialog.ShowDialog() > $null
    $FolderBrowserDialog.SelectedPath
}

Here is an updated (PSVersion 5.1 and newer) version of JG in SD's post:

function Get-FileName {   
    
  param
  (
    $initialDirectory
  )
  
  $null = Add-Type -AssemblyName System.windows.forms

  $OpenFileDialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog
  $OpenFileDialog.initialDirectory = $initialDirectory
  $OpenFileDialog.filter = 'All files (*.*)| *.*'
  $null = $OpenFileDialog.ShowDialog()
  $OpenFileDialog.filename
}

I resolved this by using cmd.exe. I could not find a way to capture the output directly without powershell somehow disabling command completion, so I had to use Invoke-Expression and a temp file to pass back the result.

    Invoke-Expression 'cmd /v:on /c set /P file=Enter target path: `& if defined file echo !file! `> %TEMP%\temp.tmp'
    $TargetPath = $null
    If ( Test-Path -PathType Leaf "$ENV:TEMP\temp.tmp" ) { $TargetPath = (Get-Content "$ENV:TEMP\temp.tmp").Trim() 2>$null }
    Remove-Item "$ENV:TEMP\temp.tmp" 2>$null

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top