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

Mar*_*arc 2 reflection documentation powershell

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

[OutputType([String])]
param(
    [string]$name
)
Run Code Online (Sandbox Code Playgroud)

以下返回String

(Get-Command .\myScript.ps1).OutputType.Name
Run Code Online (Sandbox Code Playgroud)

但我想指定脚本返回text/jsontext/xml. 这样做的好方法是什么?

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

mkl*_*nt0 6

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

重要提示:声明的输出类型的两种方式都是唯一的信息不强制通过PowerShell的在运行时(但[OutputType]信息用于制表完成)。

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

    • 始终使用此机制,并在必要补充机制 B。

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

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

    • 至于当您可能需要使用机构B

      • 如果 .NET 类型名称不能说明全部情况,如问题中所述。

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

  • [补充] 机制 B : 使用.OUTPUTS基于评论的帮助部分

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

    • 虽然您可以单独使用此机制,但这样做会放弃选项卡完成和 IntelliSense 的优势。

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

      • 如果同时使用两种机制,则Get-Help 显示机制 B定义

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

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

下面的详细信息,从对原始问题的回答开始。


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

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

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

您可以在单个[OutputType()]属性中指定多种类型,也可以使用单个属性。
必须,如果你想使用各个属性映射输出类型来具体参数集(例如,[OutputType([string], ParameterSetName='NameOnly')])。
但是,从 Windows PowerShell v5.1 / PowerShell Core v6.0.1 开始,此信息既不被 Tab 补全 / IntelliSense 使用,也不反映在Get-Help -Full.

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

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

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

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

除此之外,

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

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

如前所述,尽管它的约束性质,OutputType属性纯粹是在运行时信息-但它是,用于标签完成和智能(Visual Studio代码)


使用自定义类型的示例:

# 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
  )
}
Run Code Online (Sandbox Code Playgroud)

然后你得到:

PS> (Get-Command foo).OutputType.Name
org.example.text_json
Run Code Online (Sandbox Code Playgroud)

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

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


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

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

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

.OUTPUTS节使用帮助主题中的示例建议的以下格式,但请注意,文本最终是自由格式的,并且不强制执行任何结构。

<type-name> <optional-description>
Run Code Online (Sandbox Code Playgroud)

尽管帮助主题(从 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()
}
Run Code Online (Sandbox Code Playgroud)

请注意,当Get-Help用于查看整个帮助时,(聚合).OUTPUTS(和.INPUTS)部分仅显示为Get-Help -Full

编程方式查询该信息基本上会逐字生成该OUTPUTS部分
Get-Help -Full.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].
Run Code Online (Sandbox Code Playgroud)

要单独访问描述,请按索引:

PS> (Get-Help foo).returnvalues.returnvalue[0].type.name
text/json. In case of x, returns a JSON [string].
Run Code Online (Sandbox Code Playgroud)

但是,考虑到描述的自由形式性质以及它们是供人类使用的,可能不需要这种细粒度的访问。

也就是说,使用这种形式返回没有多余空格的文本,因此(Get-Help foo).returnvalues.returnvalue.type.name可用于返回没有空行的所有文本。

这类似于以下.INPUTS部分:
(Get-Help foo).inputTypes.inputType.type.name