Powershell: ArgumentCompleter behavior changed with PowerShell 7

Created on 30 Apr 2020  路  2Comments  路  Source: PowerShell/PowerShell

Steps to reproduce

I've played around with a lot of other Get-xxxxxx cmdlets and Get-ChildItem seems to be the only one having a different result between the two PowerShell versions.

param(
    [ArgumentCompleter( {
        Get-ChildItem
    })]
    $Object
)

Expected behavior

Formerly returned the file/folder name.

Actual behavior

Now returns the full path.

Environment data

Name                           Value
----                           -----
PSVersion                      7.0.0
PSEdition                      Core
GitCommitId                    7.0.0
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Issue-Question Resolution-Answered

Most helpful comment

This is due to FileSystemInfo.ToString changing in .NET itself. This issue was discussed in #7132 and it was ultimately decided by the PowerShell committee to maintain this behavior in #7132 (comment):

The work involved to maintain compatibility is not worth the effort as the underlying platform has introduced a change to fix an inconsistency problem. This results in a breaking change for some PowerShell users, but detecting of this will be quick and using .FullName or .Name as appropriate is the right thing to do. We could make a change in Join-Path to support joining two absolute paths to make this simpler for scripts, but that would be a separate issue.

Generally speaking it's best to avoid depending on stringification anyway. Instead, use the property that explicitly holds the string you're looking for:

param(
    [ArgumentCompleter( {
        (Get-ChildItem).Name
    })]
    $Object
)

All 2 comments

This is due to FileSystemInfo.ToString changing in .NET itself. This issue was discussed in #7132 and it was ultimately decided by the PowerShell committee to maintain this behavior in #7132 (comment):

The work involved to maintain compatibility is not worth the effort as the underlying platform has introduced a change to fix an inconsistency problem. This results in a breaking change for some PowerShell users, but detecting of this will be quick and using .FullName or .Name as appropriate is the right thing to do. We could make a change in Join-Path to support joining two absolute paths to make this simpler for scripts, but that would be a separate issue.

Generally speaking it's best to avoid depending on stringification anyway. Instead, use the property that explicitly holds the string you're looking for:

param(
    [ArgumentCompleter( {
        (Get-ChildItem).Name
    })]
    $Object
)

Thanks for the explanation :)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rkeithhill picture rkeithhill  路  3Comments

concentrateddon picture concentrateddon  路  3Comments

pcgeek86 picture pcgeek86  路  3Comments

andschwa picture andschwa  路  3Comments

alx9r picture alx9r  路  3Comments