简体   繁体   中英

I have a function that returns a PSCustomObject with specific named properties. How can I get these named properties to appear in autocomplete?

Here is a simple function that splits a file path into its individual components and assigns them to a handful of properties:

function Get-FilePathComponents {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory,Position=0,ValueFromPipeline)]
        [String[]]
        $Path
    )

    begin {}

    process {

        foreach ($P in $Path) {
            [PSCustomObject]@{
                ContainingFolder     = Split-Path $P -Parent
                FileBaseName         = Split-Path $P -LeafBase
                FileFullName         = Split-Path $P -Leaf
                FileExtension        = Split-Path $P -Extension
                FullPathNoExtension  = [IO.Path]::Combine((Split-Path $P -Parent),(Split-Path $P -LeafBase))
                CompletePath         = $P
                ParentFolder         = Split-Path (Split-Path $P -Parent) -Parent
            }
        }
    }
}

I then use the function like this:

$DestFile = "C:\Images\Wallpapers\SomeCoolWallpaper.jpg"
$Components = Get-FilePathComponents $DestFile

$Components.FileFullName     # Outputs SomeCoolWallpaper.jpg
$Components.ContainingFolder # Outputs C:\Images\Wallpapers

What I really need to accomplish is to somehow enable autocompletion for the returned object and its important properties.

This image below is exactly what I want:

自动完成

I was able to get it to work by defining a custom types.ps1xml file and populating it with <ScriptProperty> members that correspond to my parameters:

<Types>
<Type>
<Name>VSYSFileOps.Object.FilePathComponents</Name>

<ScriptProperty>
   <Name>ContainingFolder</Name>
   <GetScriptBlock>
      $this.ContainingFolder
   </GetScriptBlock>
</ScriptProperty>

<ScriptProperty>
   <Name>FileBaseName</Name>
   <GetScriptBlock>
      $this.FileBaseName
   </GetScriptBlock>
</ScriptProperty>

<ScriptProperty>
   <Name>FileFullName</Name>
   <GetScriptBlock>
      $this.FileFullName
   </GetScriptBlock>
</ScriptProperty>

... Etc...

And then adding [OutputType('VSYSFileOps.Object.FilePathComponents')] to the beginning of my function. Surprisingly, while this seems to work, I've been informed by some very knowledgeable people that this is a very bad idea and not what ps1xml files are used for.

I really want to get auto-completion working for this. How can I make this happen?

Any help at all would be extremely welcomed.

Edit: I am using VSCode with the official PowerShell extension and Powershell Pro Tools.

If you want to go the custom class route, you can add a custom class as a type definition or by loading the class code in a script file/console:

# class definition
$class = @'
public class FilePathComponents
{
    public string ContainingFolder { get;set; }
    public string FileBaseName { get;set; }
    public string FileFullName { get;set; }
    public string FileExtension { get;set; }
    public string FullPathNoExtension { get;set; }
    public string CompletePath { get;set; }
    public string ParentFolder { get;set; }
}
'@
# add class to PowerShell session
Add-Type -TypeDefinition $class
# define function
function Get-FilePathComponents {

    [CmdletBinding()]
    param (
        [Parameter(Mandatory,Position=0,ValueFromPipeline)]
        [String[]]
        $Path
    )

    begin {}

    process {

        foreach ($P in $Path) {
            $obj = [FilePathComponents]::new()
            $obj.ContainingFolder     = Split-Path $P -Parent
            $obj.FileBaseName         = Split-Path $P -LeafBase
            $obj.FileFullName         = Split-Path $P -Leaf
            $obj.FileExtension        = Split-Path $P -Extension
            $obj.FullPathNoExtension  = [IO.Path]::Combine((Split-Path $P -Parent),(Split-Path $P -LeafBase))
            $obj.CompletePath         = $P
            $obj.ParentFolder         = Split-Path (Split-Path $P -Parent) -Parent
            $obj
        }
    }
}

# call your function
$file = Get-FilePathComponents C:\temp\test1\a.csv
# use $file. to auto-populate the properties

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM