在PowerShell中可以为脚本定义输出类型。考虑myScript.ps1
:
[OutputType([String])]
param(
[string]$name
)
下面返回String
:
(Get-Command .myScript.ps1).OutputType.Name
但是我想指定脚本返回text/json
或text/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/json
或text/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