代码之家  ›  专栏  ›  技术社区  ›  rivy

如何向PowerShell PSDrive“function:”上的函数对象添加属性?

  •  3
  • rivy  · 技术社区  · 17 年前

    以下是我尝试的结果(全部失败):


    $=>function foo { "foo" }
    $=>$f = $function:foo
    $=>$f = $f | add-member noteproperty bar BARvalue -pass
    $=>$f | gm b*
    
       TypeName: System.Management.Automation.ScriptBlock
    
    Name                 MemberType   Definition
    ----                 ----------   ----------
    bar                  NoteProperty System.String bar=BARvalue
    

    $=>set-item function:f  $f -force
    $=>$function:foo | gm b*
    >
    

    $=>$function:f = $f
    $=>$function:foo | gm b*
    >
    

    3.

    $=>$f = get-item function:foo
    $=>$f | gm
    
       TypeName: System.Management.Automation.FunctionInfo
    
    Name                MemberType   Definition
    ----                ----------   ----------
    Equals              Method       System.Boolean Equals(Object obj)
    GetHashCode         Method       System.Int32 GetHashCode()
    GetType             Method       System.Type GetType()
    ToString            Method       System.String ToString()
    PSDrive             NoteProperty System.Management.Automation.PSDriveInfo PSDrive=Function
    PSIsContainer       NoteProperty System.Boolean PSIsContainer=False
    PSPath              NoteProperty System.String PSPath=Microsoft.PowerShell.Core\Function::foo
    PSProvider          NoteProperty System.Management.Automation.ProviderInfo PSProvider=Microsoft....
    CmdletBinding       Property     System.Boolean CmdletBinding {get;}
    CommandType         Property     System.Management.Automation.CommandTypes CommandType {get;}
    DefaultParameterSet Property     System.String DefaultParameterSet {get;}
    Definition          Property     System.String Definition {get;}
    Description         Property     System.String Description {get;set;}
    Module              Property     System.Management.Automation.PSModuleInfo Module {get;}
    ModuleName          Property     System.String ModuleName {get;}
    Name                Property     System.String Name {get;}
    Options             Property     System.Management.Automation.ScopedItemOptions Options {get;set;}
    Parameters          Property     System.Collections.Generic.Dictionary`2[[System.String, mscorli...
    ParameterSets       Property     System.Collections.ObjectModel.ReadOnlyCollection`1[[System.Man...
    ScriptBlock         Property     System.Management.Automation.ScriptBlock ScriptBlock {get;}
    Visibility          Property     System.Management.Automation.SessionStateEntryVisibility Visibi...
    
    $=>$f = $f | add-member noteproperty bar barValue -pass
    $=>$f | gm b*
    
       TypeName: System.Management.Automation.FunctionInfo
    
    Name                MemberType   Definition
    ----                ----------   ----------
    bar                 NoteProperty System.String bar=barValue
    
    $=>set-item function:foo $f
    $=>$function:foo | gm b*
    >
    

    不知道我做错了什么。重新分配时,这些房产似乎被剥离了。对吗?定义的行为?我没有看到任何文档说FunctionInfo对象或ScriptBlocks被异常处理。这是语言的一个深奥的角落吗?

    1 回复  |  直到 10 年前
        1
  •  4
  •   Steven Murawski    17 年前

    我的第一个想法是,当你将这个属性附加到一个对象时,你是在将它附加到该对象的一个特定实例上。当你的变量失去对该对象的引用时,对该新属性的任何了解都会丢失。

    我的猜测是,下次你得到那个项目时,你正在创建一个具有foo属性的新FunctionInfo对象(存储在函数提供者中)。

    当您调用Get-Item或Get-ChildItem时,它会返回对的对象引用。NET类型,表示底层项。这些项目不会无限期地存在于内存中(想象一下,每个本地驱动器上的每个文件和内存中的每个映射驱动器都有一个FileInfo对象……哎哟)。由于每次调用Get-Item时PowerShell都会创建一个新实例,因此您将获得基本的FunctionInfo对象。

    如果你想为特定类型的所有项目添加属性,你可以使用PowerShell的可扩展类型系统。您可以创建一个自定义的.ps1xml文件,并将其加载到PowerShell会话中,该会话可以向类型的每个实例添加属性。PowerShell团队博客上的一些很好的例子在这里-> Hate Add-Member Leveraging the PowerShell Type Extensions to Get Documentation .

    此外,函数提供程序(函数:psdrive)没有存储该附加属性的机制。它知道并使用FunctionInfo对象。当您从Function:PSDrive请求项目时,Function提供程序会返回一个FunctionInfo对象。当您将函数保存到function:PSDrive时,提供程序只能存储它知道如何处理的属性的值。可以编写一个自定义提供程序来处理PSObject包装器中的新属性,但这不是此提供程序默认功能的一部分。

    编辑2:好吧,这一直困扰着我。 I blogged about a workaround .

    推荐文章