我写了小测试代码:
namespace Test {
using System;
using System.Management.Automation;
using System.Linq;
using System.IO;
[Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName="Path")]
public sealed class GetTestCommand : PSCmdlet {
private String[] _paths;
private Boolean _wildcards;
[Parameter(
ParameterSetName="Path",
Mandatory=true,
Position=0,
ValueFromPipeline=true,
ValueFromPipelineByPropertyName=true
)]
public String[] Path {
get { return _paths; }
set {
_wildcards = true;
_paths = value;
}
}
[Parameter(
ParameterSetName="LiteralPath",
Mandatory=true,
Position=0,
ValueFromPipeline=false,
ValueFromPipelineByPropertyName=true
)]
public String[] LiteralPath {
get { return _paths; }
set { _paths = value; }
}
protected override void ProcessRecord() {
ProviderInfo pi;
(from p in _paths
select new {
FilePath = (_wildcards ?
this.SessionState.Path.GetResolvedProviderPathFromPSPath(p, out pi)[0] :
this.SessionState.Path.GetUnresolvedProviderPathFromPSPath(p))
}).ToList()
.ForEach(i => WriteObject(i.FilePath));
}
}
}
这个有效:
Get-Test *.txt
这有效:
Get-ChildItem -Filter *.txt | Get-Test
但这行不通:
Get-ChildItem -Filter *.txt -Recurse | Get-Test
请向我解释哪里出了问题、如何解决以及我应该阅读哪些内容以深入了解 PowerShell 的机制。
最佳答案
问题是您实际上没有处理从 Powershell cmdlet
收到的对象。
正确的做法是将接收到的参数绑定(bind)到适当类型的对象,然后访问其属性,即:
[Cmdlet(VerbsCommon.Get, "Test", DefaultParameterSetName = "Path")]
public sealed class GetTestCommand : PSCmdlet
{
private FileSystemInfo[] _paths;
[Parameter(
ParameterSetName = "Path",
Mandatory = true,
Position = 0,
ValueFromPipeline = true,
ValueFromPipelineByPropertyName = true
)]
public FileSystemInfo[] Path
{
get { return _paths; }
set
{
_paths = value;
}
}
protected override void ProcessRecord()
{
ProviderInfo pi;
(from p in _paths
where (p.GetType() != typeof(DirectoryInfo))
select new
{
FilePath = p.FullName}).ToList()
.ForEach(i => WriteObject(i.FilePath));
}
}
为了将来引用,您可能需要使用 Get-ChildItem | 检查从
.
更重要的是,您实际上可以使用 cmdlet
接收到的类型foreach-object-process { $_.GetType() } Powershell
以相同的方式实现您想要的,例如:Get-ChildItem | foreach-object-process { $_.FullName }
.
要获得与纯 Powershell
完全相同的结果,请尝试:
Get-ChildItem -Recurse | ForEach-Object -Process { if ($_ -isnot [System.IO.DirectoryInfo]) { Write-Host $_.FullName } }
关于c# - 从 cmdlet 中的管道正确获取文件路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34570328/