PowerShell 反射:将 MIME 类型或子类型定义为脚本的输出类型



在PowerShell中可以为脚本定义输出类型。考虑myScript.ps1:

[OutputType([String])]
param(
[string]$name
)

下面返回String:

(Get-Command .myScript.ps1).OutputType.Name

但是我想指定脚本返回text/jsontext/xml。有什么好办法呢?

为OutputType(例如[String.JSON])创建类型不起作用。

两种独立但互补的机制来声明输出类型:

重要:声明输出类型的两种方式都是信息,只有在运行时不被PowerShell强制执行(但是[OutputType]信息用于制表符完成)。

  • 机制一个param()声明之上使用[OutputType]属性在脚本或函数中,如问题:

    • 始终使用此机制,并且,必要时用机制b补充

    • 只识别完整类型名.NET类型或PowerShell类型加速器的名称并且不执行预先验证,但是如果在调用时遇到无法识别的类型:

      • 如果最初指定为字符串(例如,'System.Text.Encoding'):它被悄悄地忽略
      • 如果最初指定为类型文字(例如,[System.Text.Encoding]):函数调用在调用
      • 时中断
    • 这个严格的,基于类型的集成启用选项卡补全/智能感知(命令行/Visual Studio Code)

    • 至于,当您可能想要使用机制B:

      • 如果。net类型名称没有说明全部情况,如问题所示。

      • 如果一个函数输出多种类型,你想口头描述什么类型输出时。

  • (补充) 机制B:使用基于注释的帮助的.OUTPUTS部分:

    • 接受自由格式描述;虽然引用实际的类型名是有意义的,但这样做并不是强制的。

    • 虽然可以单独使用这种机制,但这样做会放弃制表符完成和智能感知的优点。

    • 因此,如果需要,使用来补充机制A,但请注意:

      • 如果两种机制都被使用,Get-Help只有显示机制B定义.

      • 由于这两种机制是独立的,您必须手动确保指定的自由格式信息完整一致

人眼检查输出类型信息,使用(Get-Help <cmd>).returnvalues(注意:需要定义帮助,例如通过基于注释的帮助)或从Get-Help -Full <cmd>读取输出的OUTPUTS部分。.
这将显示自由格式的.OUTPUTS内容,或者在没有[OutputType[]]内容的情况下,显示CC_17声明类型的完整类型名称。
对于编程访问,使用(Get-Command <cmd>).OutputType,返回.Type属性包含实际类型的[System.Management.Automation.PSTypeName]实例。

详细信息如下,从原始问题的答案开始。


机制A:在params()之上使用OutputType属性:

只能指定。. NET将作为OutputType属性的参数。因此,像text/jsontext/xml这样反映MIME类型的字符串将不起作用。

如果你想要字符串输出,你已经选择了最接近你的MIME类型的。net类型:[OutputType([String])]

您可以在单个[OutputType()]属性中指定多个类型,也可以使用单个属性。
如果您想将输出类型映射到特定的参数集,则必须使用单独的属性(例如,[OutputType([string], ParameterSetName='NameOnly')])。
从Windows PowerShell v5.1/PowerShell Core v6.0.1开始,这些信息既不被选项卡完成/智能感知使用,也不反映在Get-Help -Full的输出中。

注意:对于要被OutputType属性识别的类型在调用时,

  • 使用完整的类型名称(例如,[System.Text.RegularExpressions.Match]而不仅仅是[Match])或PowerShell类型加速器的名称,如[regex]

    • 如果有疑问,在提示符下输入[<fullTypeName>],看看它是否被识别为类型;另外,您可以选择将类型指定为字符串(例如,'System.Text.Encoding')或作为类型文字(例如,(例如,[System.Text.Encoding]),这具有行为含义-见下文
  • 如果指定的类型在调用时不存在,例如,由于包含类型的程序集尚未加载,因此行为取决于如何声明输出:

    • 如果最初指定为字符串:它被忽略。
    • 如果最初指定为类型文字:函数调用在调用
    • 时中断

除此之外,

  • 要么:简单地描述您的cmdlet在其帮助文本中输出的特定类型的字符串,例如通过下面描述的机制B,

  • 或:create自定义。net类型,其名称反映所需的概念类型,并在OutputType属性中指定它们-见下文。

如前所述,尽管OutputType属性具有约束性质,但在运行时是纯粹的信息。-然而,用于选项卡补全和智能感知(Visual Studio Code).


使用自定义类型的示例:

# Define an empty custom type for the sole purpose for being able to use
# it with the OutputType attribute.
# Note: On first call, this may take a second or two, as the code is being
#       compiled.
Add-Type @'
namespace org.example {
public class text_json {}
}
'@
function foo {
# Reference the custom type defined above; full type name required.
[OutputType([org.example.text_json])]
param(
[string]$name
)
}

则得到:

PS> (Get-Command foo).OutputType.Name
org.example.text_json

请注意,.OutputType输出的[System.Management.Automation.PSTypeName]实例与您直接检查类型时得到的[type]实例不同:

[System.Management.Automation.PSTypeName].Name属性对应于[type].FullName属性,所以如果类型被识别(在会话中可用),您将获得完整的类型名称;否则,它就是最初指定的名称。


机制B:在基于注释的帮助中使用.OUTPUTS部分:

概念帮助主题Get-Help about_Comment_Based_Help描述了如何使用基于注释的脚本和函数帮助中的.OUTPUTS节列出和描述输出类型。

注意:类似地,.INPUTS节可以用来描述支持的输入类型,尽管这可能不那么有趣,因为指定输入类型是参数声明和文档的一个组成部分。总的来说,.INPUTS的功能类似于.OUTPUTS,只有下面提到的不同之处。

.OUTPUTS部分使用帮助主题中的示例建议的以下格式,但请注意,文本最终是自由格式的,并且没有强制结构

<type-name> <optional-description>

尽管帮助主题(如PSv5)没有提到它,但似乎在多种输出类型的情况下,每种类型都应该在其自己的.OUTPUTS部分中进行描述。也就是说,自由格式允许在单个部分中描述多个输出类型描述。

示例,利用自由格式以MIME类型描述输出:

<#
.SYNOPSIS
Does stuff.
.OUTPUTS
text/json. In case of x, returns a JSON [string].
.OUTPUTS
text/xml. In case of y, returns an XML [string].
#>
function foo {
param()
}

请注意,当使用Get-Help整体查看帮助时,(聚合的).OUTPUTS(和.INPUTS)部分仅与Get-Help -Full一起显示。

以编程方式查询信息本质上是从
Get-Help -Full逐字生成OUTPUTS部分(源中的单个.OUTPUTS部分之间连接一个空行,以及额外的尾随空行):

PS> (Get-Help foo).returnvalues
text/json. In case of x, returns a JSON [string].
text/xml. In case of y, returns an XML [string].

单独访问描述,通过索引:

PS> (Get-Help foo).returnvalues.returnvalue[0].type.name
text/json. In case of x, returns a JSON [string].
然而,考虑到描述的自由形式性质,以及它们是为使用的,这种粒度访问可能不需要。

也就是说,使用这种形式返回没有额外空白的文本,所以(Get-Help foo).returnvalues.returnvalue.type.name可以用来返回所有没有空行的文本。


(Get-Help foo).inputTypes.inputType.type.name

一个简洁的方法是使用PowerShell帮助注释语法。

<# 
.Synopsis
Returns a list of files.
.Description
...
.Inputs
text/csv
.Outputs
text/json[]
#>

您可以从Get-Help对象访问此信息:

$cmd = Get-Help -Name .componentsFileList.ps1
"Input Type: " + $cmd.inputTypes.inputType[0].type.name
"Output Type: " + $cmd.returnValues.returnValue[0].type.name

结果:

Input Type: text/csv
Output Type: text/json[]

也适用于标准的cmdlet:

(Get-Help Get-Date).returnValues[0].returnValue[0].type.name

的回报:

System.DateTime or System.String

相关内容

  • 没有找到相关文章

最新更新