简体   繁体   English

我有一个 function ,它返回一个具有特定命名属性的 PSCustomObject 。 如何让这些命名属性出现在自动完成中?

[英]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 ,它将文件路径拆分为各个组件并将它们分配给一些属性:

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:然后我像这样使用 function:

$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.我真正需要完成的是以某种方式为返回的 object 及其重要属性启用自动完成功能。

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.ps1xml 文件并使用与我的参数对应的<ScriptProperty>成员填充它来使其工作:

<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.然后将[OutputType('VSYSFileOps.Object.FilePathComponents')]添加到我的 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.令人惊讶的是,虽然这似乎可行,但一些知识渊博的人告诉我,这是一个非常糟糕的主意,而不是 ps1xml 文件的用途。

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.编辑:我正在使用带有官方 PowerShell 扩展和 Powershell Pro Tools 的 VSCode。

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: 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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